El uso de punteros de 32 bits en Linux de 64 bits reduce el uso de memoria un 25 por ciento
La ABI x32 permite a las aplicaciones utilizar punteros de 32 bits manteniendo los registros de 64 bits, lo que reduce significativamente el uso de RAM sin sacrificar la velocidad.
Traducido automáticamente del original en inglés.
El ingeniero de software Alex Alejandre demostró recientemente que compilar el lenguaje de programación Janet con la Interfaz Binaria de Aplicación (ABI) x32 de Linux reduce el consumo de memoria aproximadamente un 21 por ciento. Esta optimización aprovecha los punteros de 32 bits en sistemas de 64 bits, manteniendo velocidades de ejecución comparables mientras se reduce la huella de memoria de los objetos del heap. Los hallazgos sugieren una vía viable para un uso más eficiente de los recursos en scripts, utilidades y demonios que se ejecutan en Linux.
Qué ocurrió
Alejandre probó el impacto de la opción del compilador -mx32 en Janet, un lenguaje de programación dinámico conocido por su diseño ligero. En modo estándar de 64 bits, Janet utiliza "nanboxing" para empaquetar valores en 8 bytes, lo cual ya optimiza el uso de memoria. Sin embargo, cambiar a la ABI x32 produjo reducciones adicionales porque disminuye el tamaño de las cabeceras de objeto y de los punteros. Las pruebas mostraron una reducción de memoria entre el 8 y el 32 por ciento, con un ahorro promedio del 21 por ciento. El rendimiento se mantuvo estable, variando desde un 13 por ciento más lento hasta un 10 por ciento más rápido que la compilación nativa de 64 bits.
En contraste, el uso de la opción tradicional de compilación de 32 bits (-x32) resultó en una penalización significativa de rendimiento, reduciendo la velocidad a la mitad. Esto destaca la ventaja única de la ABI x32: conserva el conjunto más amplio de registros de propósito general y el juego de instrucciones de x86-64 mientras utiliza punteros más pequeños. Alejandre señaló que este enfoque es particularmente efectivo para heaps intensivos en punteros, donde la reducción del tamaño del puntero se traduce directamente en menor presión sobre la memoria y mejor utilización de la caché.
El experimento también reveló limitaciones dentro de la gestión actual de memoria de Janet. Los objetos del heap de Janet utilizan actualmente 16 bytes para asistir al recolector de basura, incluyendo banderas, relleno y punteros de enlace. Si bien la ABI x32 ayuda, optimizaciones más profundas requerirían cambios en el asignador o en la estrategia de recolección de basura. Alejandre indicó que malloc de glibc añade sobrecarga y redondea las asignaciones a múltiplos de 16 bytes, lo que limita algunos ahorros potenciales para estructuras de datos específicas como los structs. No obstante, las tablas y ciertos tuples aún se benefician del tamaño reducido de los punteros.
Cómo funciona
La ABI x32 es una característica específica de Linux que permite a los programas ejecutarse en modo de 64 bits pero utilizando punteros de 32 bits. Normalmente, los sistemas de 64 bits usan punteros de 8 bytes, lo cual puede desperdiciar memoria al direccionar datos que no superan los 4 gigabytes. Al cambiar a punteros de 4 bytes, las aplicaciones reducen el tamaño de cada estructura de datos que contiene una referencia. Esta reducción significa que cabe más datos en la caché de la CPU, lo que puede mejorar el rendimiento a pesar del espacio de direcciones más pequeño.
Para usar esta función, el kernel de Linux debe estar compilado con CONFIG_X86_X32_ABI, que proporciona los puntos de entrada syscall necesarios. Los compiladores exponen esta capacidad mediante la opción -mx32. A diferencia del modo puro de 32 bits, x32 mantiene el conjunto completo de registros e instrucciones de 64 bits, evitando los cuellos de botella de rendimiento asociados con la ejecución heredada de 32 bits. Esto lo convierte en una opción atractiva para servidores y aplicaciones de escritorio que no necesitan direccionar más de 4 GB de memoria por proceso.
Detalles clave
- La opción
-mx32redujo el uso de RAM de Janet en un promedio del 21 por ciento, con resultados que oscilaron entre el 8 y el 32 por ciento. - La velocidad de ejecución permaneció comparable a las compilaciones nativas de 64 bits, variando desde un 13 por ciento más lento hasta un 10 por ciento más rápido.
- La compilación tradicional de 32 bits (
-x32) causó una caída del 50 por ciento en el rendimiento, haciéndola inadecuada para tareas sensibles al rendimiento. - La ABI x32 requiere soporte del kernel de Linux mediante
CONFIG_X86_X32_ABIy está deshabilitada por defecto en distribuciones como Debian y Arch Linux. - Los ahorros de memoria son más pronunciados en aplicaciones con heaps intensivos en punteros, como aquellas que gestionan muchos objetos pequeños.
- La sobrecarga de
mallocde Glibc y los requisitos de alineación de 16 bytes limitan algunos ahorros potenciales para estructuras de datos específicas como los structs.
Por qué importa
Para los desarrolladores que construyen infraestructura, scripts o demonios de larga duración, la eficiencia de memoria impacta directamente en el costo y la escalabilidad. Una reducción del 21 por ciento en el uso de RAM permite ejecutar más instancias en el mismo hardware o reduce la necesidad de sobreaprovisionamiento. Esto es particularmente relevante en entornos contenedorizados donde los límites de memoria son estrictos. La ABI x32 ofrece una forma de lograr estos ahorros sin reescribir código ni cambiar algoritmos, simplemente ajustando las opciones de compilación.
La subutilización de x32 representa una oportunidad perdida para el ecosistema Linux. Aunque la mayoría del software se compila limpiamente para x32, la falta de paquetes precompilados obliga a los desarrolladores a compilar las dependencias ellos mismos. Esta barrera desalienta la adopción, aunque los beneficios sean claros para muchas cargas de trabajo. Si las principales distribuciones habilitaran el soporte x32 por defecto, podría conducir a ganancias generalizadas de eficiencia en el panorama de servidores, reduciendo el consumo energético y los requisitos de hardware.
Qué puedes hacer
- Comprueba si tu kernel de Linux soporta x32 buscando
CONFIG_X86_X32_ABIen la configuración de tu kernel. - Experimenta compilando pequeñas utilidades o demonios usando la opción
-mx32para medir los impactos en memoria y rendimiento. - Investiga si tu distribución proporciona bibliotecas x32 o si necesitas compilar manualmente las dependencias cruzadas.
- Perfiliza aplicaciones intensivas en punteros para identificar candidatos que se beneficiarían más de tamaños de puntero reducidos.
- Considera usar asignadores más rápidos como mimalloc junto con x32 para maximizar las ganancias de rendimiento.
- Aboga por un mejor soporte de x32 en tu distribución Linux preferida solicitando paquetes precompilados para herramientas comunes.



