El regreso de los punteros de marco

Compromisos de rendimiento de los punteros de marco

  • Los costos principales que se discuten son: un registro de propósito general menos (grave en x86 de 32 bits, menor en x86_64 y otras ISA) e instrucciones adicionales de prólogo/epílogo que pueden inflar funciones pequeñas y frecuentes, además de presionar la I‑cache.
  • Las ralentizaciones reportadas varían mucho: algunos ven ~1–3% en aplicaciones reales; una prueba de Phoronix informó una penalización media geométrica de ~14%; mediciones del kernel citaron 5–10% para algunas cargas de trabajo; otros afirman “menos del 1%” a nivel de distribución con toolchains modernos.
  • Desacuerdo sobre la calidad de los benchmarks: algunos llaman a las pruebas de bases de datos “microbenchmarks”, mientras otros sostienen que son pruebas realistas de extremo a extremo. El consenso es que el impacto depende de la carga de trabajo y no está caracterizado de forma universal.
  • x86 de 32 bits sigue considerándose particularmente escaso en registros; para muchas otras arquitecturas, el registro perdido se ve como insignificante.

Perfilado, depuración y por qué importan los FPs

  • Muchos consideran esenciales las trazas de pila fiables y de bajo overhead para el perfilado de CPU, memoria y, especialmente, fuera de CPU, así como para el rastreo de ejecución.
  • Sin punteros de marco, perf del kernel debe copiar grandes fragmentos de la pila y hacer el unwinding después, lo que causa overhead de CPU, memoria y disco, y requiere paquetes de depuración.
  • Los desarrolladores argumentan que “simplemente recompilar con FPs” es poco realista cuando intervienen sistemas completos y bibliotecas de terceros, y hace impráctico pedir trazas a los usuarios finales.
  • Algunos señalan que un perfilado mejorado ha producido mejoras de rendimiento de >10–20% en software real, superando fácilmente un pequeño overhead global de FP.

DWARF y enfoques alternativos de unwinding

  • El unwinding con DWARF/.eh_frame se describe como flexible, pero complejo y lento para muestreos de alta frecuencia o perfilado fuera de CPU. La ruta DWARF actual de perf es especialmente costosa debido a la copia de la pila.
  • Otros afirman que DWARF puede hacerse rápido precargando y cacheando la información de unwinding, y señalan perfiladores basados en eBPF que convierten tablas a formatos eficientes en el kernel.
  • JVM/JIT y otros runtimes de alto nivel siguen siendo difíciles: el unwinding personalizado, las pilas mixtas nativas/gestionadas y la intensa actividad de JIT hacen que las soluciones solo con DWARF sean frágiles o demasiado caras a escala.

Valores predeterminados, políticas de distro y quién paga el costo

  • El debate se centra en cuál debería ser el valor predeterminado para kernels, libc y compilaciones de distro.
  • Un lado: habilitar FPs globalmente para que el perfilado de todo el sistema “simplemente funcione”, permitiendo la optimización continua y el análisis posterior de las versiones en producción.
  • El otro lado: la mayoría de los usuarios nunca perfila; unos pocos puntos porcentuales de pérdida en millones de dispositivos y servidores no son triviales en energía y coste; el código sensible al rendimiento puede habilitar FPs solo en compilaciones de desarrollo.
  • Las sugerencias incluyen atributos por función (con advertencias), compilaciones separadas de libc “dev” frente a “end-user”, y el uso de sistemas basados en código fuente o Nix/Guix para alternar la política a nivel de sistema.

Seguridad e ideas de arquitectura

  • Se discuten pilas separadas o sombra para direcciones de retorno como un diseño más limpio y seguro, pero el hardware actual y la compatibilidad con ABI limitan el despliegue práctico.
  • Algunos proponen prohibir alloca() en lugar de pagar el costo de FP; otros replican que los FPs al menos pueden desplegarse ahora, mientras que cambios más radicales no lo son.