Síguenos

Tecnología

¿Linux 7.0 barre la RAM un 75% más rápido? Así se consigue ya

Foto del avatar

Publicado

el

Linux 7.0 75% más rápido

Linux 7.0 promete acelerar la liberación de memoria en caché hasta un 75% con parches de Baolin Wang y folios grandes que reducen latencias.

Linux 7.0 aún está en fase de desarrollo, pero ya trae una mejora muy concreta que ha hecho levantar cejas en la comunidad: la recuperación de memoria (reclaim) para caché de archivos con folios grandes puede acelerarse hasta un 75% en un escenario de prueba muy específico. No es un “Linux entero va un 75% más rápido”, ni un truco de laboratorio sin nombre propio: el trabajo lo firma Baolin Wang, ingeniero en Alibaba, y se centra en uno de esos momentos delicados en los que el sistema necesita liberar RAM con rapidez, sin bloquearse, sin dar bandazos, sin convertir el rendimiento en una montaña rusa.

El cambio llega en forma de parches para el kernel que optimizan cómo se comprueba si ciertas páginas/folios “se han usado recientemente” y, sobre todo, cómo se desmapean en bloque regiones de memoria respaldadas por archivos cuando toca hacer sitio. Dicho en llano: cuando el kernel tiene que vaciar parte del trastero de la RAM, ahora puede hacerlo con menos viajes y menos pasos repetidos, y eso, bajo presión, se traduce en segundos que se convierten en décimas… y en sistemas grandes, esas décimas son aire.

La noticia detrás del titular: una mejora quirúrgica en el corazón de Linux

En el ecosistema Linux hay titulares que suenan a cohete y luego acaban siendo una chispa simpática. Aquí, en cambio, el foco está puesto donde suele doler de verdad: la gestión de memoria en condiciones de estrés, especialmente cuando entran en juego folios grandes “file-backed”, es decir, bloques de memoria que representan datos de archivos mapeados en RAM. No se habla de arrancar más rápido ni de que el escritorio vaya a volar por arte de magia; se habla de algo más seco, más de tripas: reclamar memoria de la caché de archivos con mucha menos fricción.

La prueba que se ha difundido en los propios textos de la serie de parches es reveladora por lo concreta: se asignan 10 GB de folios grandes limpios respaldados por archivo mediante mmap() dentro de un memory cgroup, y se fuerza la reclamación de 8 GB a través de la interfaz memory.reclaim. En ese contexto, el salto reportado es llamativo: en un servidor Arm64 de 32 núcleos se observa una mejora del 75%, y en una máquina x86 el incremento supera el 50%. Y no se queda en porcentajes abstractos: en una de las mediciones, el tiempo “real” pasa de rondar 1,018 segundos a aproximadamente 0,249 segundos, con el tiempo “sys” siguiendo el mismo patrón. Menos kernel sudando a puerta cerrada; más tiempo disponible para lo que realmente se ejecuta.

Los protagonistas del cambio: Baolin Wang y el “subsuelo” de memoria

Baolin Wang no aparece aquí como una firma decorativa. En Linux, el subsistema de memoria es un barrio con calles estrechas y tráfico pesado: cualquier modificación se mira con lupa, se discute, se ajusta, se vuelve a discutir… y suele avanzar a base de iteraciones. Esta serie no nace de la nada: dialoga con trabajo previo —en los hilos se cita, por ejemplo, a Barry Song, que había implementado técnicas similares para ciertos folios grandes anónimos— y se mueve por un terreno donde se mezclan arquitectura, eficiencia y garantías de que nada se rompe en casos raros.

Ese punto es importante, porque la mejora no es un “hack” oportunista: es una optimización que busca reducir un hotspot muy concreto. En cargas donde se reclama memoria de folios grandes respaldados por archivo y además están limpios (no requieren volcarse a disco), el kernel estaba gastando demasiados ciclos en comprobar referencias y en desmapear paso a paso. La nueva aproximación es más inteligente: agrupar operaciones, hacerlas “por tandas”, reducir el goteo de trabajo repetido que, multiplicado por miles o millones de entradas, acaba siendo un peaje.

Qué se ha medido exactamente y por qué ese 75% no es un eslogan universal

El porcentaje del 75% suena redondo, casi provocador. Pero el dato, tal como está descrito, tiene apellido y DNI: es un escenario de reclamación forzada en un cgroup, con folios grandes, mapeo de archivos, memoria limpia y el uso explícito de memory.reclaim para empujar al kernel a liberar una cantidad grande de RAM. Esto no es “abrir el navegador” ni “renderizar un vídeo”, aunque ambos pueden tocar piezas relacionadas; es una prueba diseñada para tensar un camino interno del kernel y ver cuánto se ha adelgazado.

El detalle fino, el que separa un titular inflado de una mejora real, es que la optimización apunta a un tramo del proceso donde Linux decide si una región de memoria está “reciente” o si puede desalojarse. En reclamación de memoria, el kernel intenta evitar tirar a la basura algo que se está usando; para eso mantiene y consulta indicadores de acceso. Cuando se trata de folios grandes, comprobar esas señales de acceso puede convertirse en una tarea repetitiva, casi mecánica, como revisar uno a uno miles de tickets cuando lo que interesa es saber si el estadio ha tenido movimiento en el último rato. Ahí estaba el atasco.

Y sí, el 75% es espectacular, pero no conviene proyectarlo como una mejora homogénea para todo tipo de equipos y usos. La propia comparación lo sugiere: en Arm64 la ganancia reportada es mayor que en x86, aunque en ambos casos es notable. La explicación tiene sentido: ciertas arquitecturas, y en particular Arm64, cuentan con mecanismos que permiten optimizaciones adicionales en el manejo de entradas contiguas en tablas de páginas. En otras palabras, el hardware y cómo representa la memoria influyen en cuánto se puede “hacer en bloque” sin coste extra.

De 33% a 75%: la pista de que el avance llegó por capas

En iteraciones previas del trabajo, se habían reportado mejoras más modestas en el mismo tipo de prueba: cifras del orden del 33% en Arm64 y alrededor del 10% en x86, junto con un descenso fuerte del peso de ciertas funciones de comprobación de referencias dentro del perfil de CPU. Ese salto entre versiones del parche es casi una confesión técnica: la ganancia grande aparece cuando la serie culmina con la pieza más ambiciosa, el desmapeo por lotes (batched unmapping) para folios grandes respaldados por archivo. Antes se afinaba la detección; después se aceleró el movimiento de tierra.

Folios grandes, mmap() y “young flags”: el cuello de botella que estaba a la vista

Para entender por qué esto importa, conviene mirar cómo se construye el escenario. mmap() permite mapear un archivo en el espacio de memoria de un proceso: se accede a datos del archivo como si fueran memoria, y el kernel gestiona qué está en RAM y qué no, apoyándose en la caché de páginas. En cargas de servidores, en bases de datos, en sistemas de analítica, en servicios que trabajan con grandes volúmenes de datos, mmap() no es una rareza; es una herramienta común. Y cuando ese mapa ocupa muchos gigabytes, la forma en la que el kernel decide “esto se va, esto se queda” se vuelve crucial.

Aquí entran los folios grandes. En el kernel, un folio es una abstracción que agrupa páginas: no se gestiona solo un ladrillo de 4 KB, sino un bloque mayor con el que se reduce overhead en ciertos caminos. Los folios grandes tienen lógica: menos metadatos por byte útil, menos trabajo por cada unidad cuando se procesa memoria a gran escala. El problema es que, si el código que recorre referencias y desmapea memoria sigue pensando “página a página”, el folio grande se convierte en un camión obligado a pasar por una garita diseñada para bicicletas. No es que el camión sea malo; es que la puerta es estrecha.

En esa garita aparece un elemento técnico con nombre simpático: el “young flag” asociado a entradas de tablas de páginas (PTE, Page Table Entries). En términos humanos: un indicador que ayuda a saber si una región se ha usado “recientemente”. La función señalada en los parches, folio_referenced_one(), revisaba ese indicador de forma secuencial para cada PTE. Con folios grandes, eso significa repetir una comprobación miles de veces. Bajo reclamación de memoria de folios grandes limpios respaldados por archivo, esa rutina pasó a aparecer como un punto caliente muy claro en perfiles de rendimiento: demasiado tiempo mirando el mismo tipo de señal una y otra vez.

La solución, en su esencia, tiene un sabor simple: comprobar y limpiar indicadores de acceso en bloque cuando sea posible, y aprovechar capacidades de arquitectura —como en Arm64 con PTE contiguos— para no hacer trabajo redundante. No es un cambio vistoso; es un cambio de esos que, cuando funcionan, casi desaparecen. Solo se nota en la gráfica de latencia que deja de ser dentada, en el servidor que respira un poco mejor cuando le aprietan el cuello.

“Batched unmapping”: la pieza que dispara la mejora y por qué importa tanto

El salto grande, el que convierte “bien” en “ojo con esto”, llega cuando la serie culmina en lo que el propio texto llama batched unmapping para folios grandes file-backed. Desmapear (unmap) aquí significa retirar, de forma controlada, asociaciones entre memoria virtual y las páginas físicas que la respaldan, en este caso páginas que vienen de un archivo mapeado. Cuando el kernel decide reclamar memoria, a menudo necesita desmapear para poder liberar. Si esto se hace página a página, la operación se convierte en un martillo de goma: funciona, pero golpea demasiadas veces.

El enfoque por lotes, en cambio, busca una idea sencilla: si un folio grande está respaldado por un conjunto de PTE presentes y consecutivos, y la operación que hay que hacer es esencialmente “limpiar esa fila” de manera uniforme, se puede actuar como quien baja un interruptor general en lugar de apagar bombillas una a una. El propio texto del parche describe el caso de folios grandes file-backed como relativamente directo porque basta con limpiar entradas PTE consecutivas presentes. Lo relevante es el “consecutivas”: ahí está el ahorro, porque se reduce el número de transiciones, bloqueos, comprobaciones y vueltas por estructuras internas.

Ahora bien, el kernel no vive solo de casos felices. En los detalles aparece una advertencia concreta que retrata bien la prudencia del cambio: no está listo para soportar el desmapeo por lotes en el caso de userfaultfd (uffd), y por eso en ese escenario se mantiene el camino tradicional, por página. Este tipo de nota es más importante de lo que parece: dice “sí, aceleramos”, pero también “no a costa de romper un mecanismo que depende de comportamiento fino y notificaciones”. En memoria, un atajo mal puesto puede ser una pesadilla.

La interfaz memory.reclaim: cuando el sistema se fuerza a sí mismo a hacer sitio

En la prueba se usa memory.reclaim, una interfaz asociada a memory cgroups, el sistema de control de recursos que permite limitar y gestionar memoria por grupos de procesos. En entornos de contenedores, plataformas de orquestación y servidores multi-tenant, los cgroups no son un detalle: son el cinturón de seguridad. Forzar reclamación desde ahí permite modelar escenarios donde un grupo necesita liberar memoria ya, por política o por presión del sistema.

Lo interesante es que esta mejora no solo acelera un caso teórico: acelera un camino que aparece precisamente cuando hay presión y hay reglas de aislamiento activas. Y ahí es donde se entiende el entusiasmo: si la reclamación forzada dentro de cgroups se vuelve mucho más rápida, el sistema puede reaccionar con menos coste cuando hay reequilibrios, cuando se despliegan nuevas cargas, cuando un contenedor “se pasa” y toca corregir sin que todo el nodo se resienta.

Impacto real: servidores, contenedores, bases de datos… y lo que no va a cambiar

En servidores, la caché de archivos (page cache) es la alfombra donde se esconde parte de la velocidad del sistema. Discos NVMe rápidos ayudan, sí, pero la RAM sigue siendo un salto de magnitud. Bases de datos, motores de búsqueda, sistemas de colas, plataformas de analítica, repositorios de objetos, pipelines de procesamiento: todos viven, de un modo u otro, del equilibrio entre tener datos calientes en memoria y liberar cuando hace falta. Cuando ese equilibrio se rompe por un pico —un despliegue, un reindexado, una ola de peticiones, una tarea batch—, lo que se nota no es “Linux va más lento”, sino algo más desagradable: latencias irregulares, pausas raras, colas que crecen como una sombra.

La mejora que se está incorporando en el ciclo de Linux 7.0 apunta justo a ese tipo de episodio. No promete milagros en un escritorio tranquilo, pero sí puede marcar diferencias en entornos donde los folios grandes respaldados por archivos son habituales y la reclamación de memoria se convierte en rutina diaria. En un servidor que hace reclaim con frecuencia, recortar tiempos del orden de 1 segundo a 0,25 segundos en un tramo concreto es como reducir un semáforo rojo largo a una parada breve: el tráfico no desaparece, pero deja de formar un atasco que contamina todo lo demás.

En x86, que sigue siendo el gran caballo de batalla, el aumento reportado por encima del 50% también es significativo, aunque menos espectacular que en Arm64. Ahí hay una lectura clara: el beneficio no depende de una sola arquitectura, pero el ecosistema Arm —cada vez más presente en centros de datos— parece especialmente bien posicionado para exprimir esta clase de optimizaciones. Y eso encaja con una tendencia de fondo: Arm64 ya no es “lo exótico”, es parte del mapa real de producción.

Dicho esto, conviene recortar expectativas donde toca. Esto no significa que compilar vaya a ser un 75% más rápido, ni que el navegador cargue en la mitad de tiempo, ni que el escritorio se convierta en un coche de carreras. El kernel tiene cientos de caminos críticos y este es uno. Lo que sí significa es que, cuando el sistema tenga que liberar memoria de una manera muy concreta, lo hará con menos coste. En sistemas complejos, eso es exactamente el tipo de mejora que, sin hacer ruido, reduce problemas.

La diferencia entre memoria “limpia” y “sucia”: por qué aquí el caso es tan favorable

La prueba habla de folios limpios respaldados por archivo. “Limpio” aquí significa que la memoria que representa esos datos no ha cambiado respecto al contenido en disco; por tanto, se puede liberar sin necesidad de escribir de vuelta. Ese detalle es clave porque libera al kernel de una parte lenta y delicada: la E/S de escritura. En reclamación de memoria, si hay páginas sucias, el proceso se complica: hay que programar escrituras, esperar, coordinar. En cambio, con memoria limpia, el kernel puede actuar con más libertad: desmapear y liberar sin pasar por la ventanilla de “antes hay que guardar”.

Por eso el número del 75% aparece en un escenario donde esa parte está “resuelta” desde el inicio. No es trampa; es un caso real y común: cachés de lectura, datos mapeados que no se modifican, páginas que simplemente están ahí para acelerar lecturas. Precisamente por ser común, una optimización ahí puede tener recorrido.

Linux 7.0 en movimiento: integración, limpieza de legado y el pulso del desarrollo

Estas mejoras se están moviendo dentro del flujo habitual del kernel, pasando por ramas de desarrollo del subsistema de memoria y aterrizando en el ciclo que alimenta Linux 7.0. En el kernel, ese tránsito es casi un rito: revisión, discusión, reenvíos, ajustes, pruebas. Que la serie llegue a integrarse en ramas de memoria gestionadas por mantenedores veteranos es una señal de madurez del cambio: no es un parche suelto en un cajón, es una pieza que se está incorporando a la maquinaria.

Y Linux 7.0 no solo asoma por estas optimizaciones. En paralelo, el ciclo también está dejando titulares de “limpieza” de código y retirada de piezas históricas que ya no aportan. Un ejemplo claro es la eliminación del controlador EDAC asociado a los chipsets Intel 440BX/440GX, un driver que llevaba años arrastrando la etiqueta de inservible y que, según se ha explicado, no funcionaba correctamente desde hace mucho tiempo por conflictos con otros controladores más usados. Aquí hay dos lecturas compatibles: por un lado, se reduce deuda técnica; por otro, se dibuja un kernel que va cerrando la puerta a reliquias que ya no se pueden sostener. No es un gesto dramático, es mantenimiento real.

Todo esto perfila una versión que, sin venderse como una revolución de cara al usuario final, sí sugiere un patrón: optimización en caminos calientes y orden en el código. En un kernel, eso pesa más que muchas funciones llamativas. La velocidad de reclamación de memoria y la salud del árbol de controladores son dos cosas distintas, pero comparten un espíritu: menos lastre, menos trabajo inútil, menos puntos donde se pierde tiempo o se acumula riesgo.

Cuándo se notará en distribuciones: el calendario real suele ir por barrios

Linux 7.0, como versión estable, llegará cuando el ciclo culmine: integración de cambios, versiones candidatas, correcciones, estabilización. A partir de ahí, cada distribución decide su ritmo. Las de actualización continua suelen incorporar kernels nuevos antes; las de soporte prolongado se mueven con más cautela o adoptan solo partes mediante backports. Este matiz importa porque una mejora como esta puede estar “lista” en el upstream, pero tardar en aterrizar en el kernel que se usa a diario en servidores o escritorios concretos.

Mientras tanto, el hecho relevante es que el trabajo está descrito con detalle técnico, con mediciones, y con una explicación clara del cuello de botella. En términos de ingeniería del kernel, eso es lo que permite que el cambio sobreviva a la revisión: no se presenta como “confíen”, sino como “aquí está el hotspot, aquí está el ajuste, aquí están los números”.

Menos tiempo reclamando memoria, más margen cuando aprieta el sistema

La historia, al final, no va de una cifra llamativa, aunque la cifra sea un buen gancho. Va de un tramo muy específico del kernel que, bajo ciertas cargas, podía convertirse en un freno: reclamar memoria de folios grandes limpios respaldados por archivos, dentro de un entorno controlado por cgroups, con reclamación forzada. Ahí, el trabajo de Baolin Wang introduce dos ideas que juntas hacen efecto: comprobaciones por lotes donde antes había inspección minuciosa PTE a PTE, y desmapeo por lotes donde antes el kernel iba desatando nudos uno por uno.

Los números encajan con esa narrativa: pasar de alrededor de un segundo a unas pocas décimas en una operación intensa no es cosmética. Es reducir el tiempo en el que el sistema está metido hasta el cuello en trabajo interno, con CPU dedicada a liberar memoria en lugar de ejecutar tareas de negocio. En servidores y cargas modernas —contenedores, servicios con picos, bases de datos con cachés grandes— esas ventanas de “trabajo interno” son donde nacen los sustos. Si se estrechan, se gana estabilidad, se gana regularidad, se gana margen.

Y hay algo más, casi silencioso: el parche no presume de universalidad, reconoce límites como el caso userfaultfd, y se apoya en mecanismos de arquitectura donde toca, especialmente en Arm64. Esa mezcla de ambición y prudencia suele ser la que deja mejoras duraderas. Linux 7.0, con este tipo de cambios, no se presenta como un espectáculo; se presenta como lo que es el kernel cuando está en forma: menos fricción donde antes había rozamiento, y un sistema que, cuando llega la presión, tarda menos en volver a respirar.

Newsletter

Fundador de DonPorqué y curioso empedernido. Escribe sobre tecnología, viajes, gastronomía, cultura y todo lo que le genera una pregunta con un buen «¿por qué?» detrás. En su tiempo libre es aficionado a los casinos online y aprovecha esa experiencia para compartir análisis y recomendaciones sobre el sector del iGaming.