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.