15 de agosto de 2006

Ahorrarse cinco MB de memoria por la cara

Arjan van de Ven ha mandado un post a la lista explicando como ha conseguido ahorrar cinco megas de memoria en su sesión de Gnome parcheando el kernel con soporte para tablas de páginas compartidas. Alucinante.

Para los que no sepan de que va eso de tablas de páginas compartidas: Todo proceso tiene un espacio de direcciones virtualizado (de 4 GB en plataformas de 32 bits) dividido en unidades de páginas (bloques de 4KB de tamaño en x86, mayores en otras arquitecturas). Cada una de esas páginas se asigna a una dirección física de memoria. Eso quiere decir que para un proceso la página número 5 puede corresponder a la página de memoria física 7, y que en otro proceso esa misma página de memoria física 7 se corresponda con la virtual 4. Los procesos no se enteran: Ellos acceden a sus páginas 5 y 4, y no saben que en realidad están compartiendo esa página física 7. La información sobre qué página virtual de cada proceso está asignada a qué página física se almacena en el kernel, en las llamadas pagetables (tablas de páginas)

Gracias a la técnica de virtualización del espacio de direcciones de los procesos tenemos cosas como las librerias compartidas: Un proceso mapea una archivo en memoria en una dirección virtual, otro proceso lo mapea tambien en otra dirección virtual propia, y el archivo se almacena en un solo lugar de la memoria física. No hay dos copias, solo una. De lo que si que se hacen dos copias es de las tablas de páginas: Cada proceso tendrá su tabla de páginas en la que se asignan las páginas virtuales del proceso a las páginas físicas de memoria. Para cada proceso, la página virtual 1 corresponderá a la páginas fisica x en la que se encuentra la primera página de bash, la 2 a la x+1, etc.

Lo que hacen las tablas de páginas compartidas es compartir la información de las tablas de páginas. Esto solo es posible si todos los procesos asignan la misma direccion virtual de su espacio de direcciones a la una misma dirección fisica: Si un proceso mapea la primera página de bash (recordar que en linux, las librerias y ejecutables son mapeadas por ld.so en el espacio de direcciones del proceso utilizando literalmente mmap()) en su página virtual 5 y otro en la 7, la información no se podría compartir. Pero se da la circunstancia de que prelink, herramienta conocida por todos, entre otras cosas coge a una determinada libreria y la asigna a la misma dirección de memoria virtual para todos los ejecutables, con lo cual todos los ejecutables del sistema mapearán una determinada librería en una dirección virtual que será la misma para todos los procesos. Esto, junto al parche de compartición de tablas de páginas, se traduce en un sistema linux en el que no solo las librerias, sino todas las tablas de páginas de esas librerias se comparten en memoria. Globalmente, en un sistema gnome se ahorra, como cuenta Arjan, 5 MB.

No es que sea una gran carencia de Linux, a pesar de que Solaris lo tiene desde hace siglos (googlear "intimate shared memory"): Se pensaba que las páginas de tablas compartidas solo tenían ventajas para algunas bases de datos en grandes servidores, y las ventajas ni eran grandes ni parecian justificar la complejidad adicional, razón por la cual hemos vivido sin ellas hasta ahora (y Dios sabe si se acabarán incluyendo). Es más, hasta ahora no se había implementado compartición de tablas de páginas para archivos mapeados en memoria, solo para la memoria compartida a propósito por procesos. A nadie le gustaba la idea de incluirlo porque algo así no iba a beneficiar a la gente normal: la prueba de arjan demuestra lo contrario. Y cinco MB menos son 5 MB menos

No hay comentarios:

Publicar un comentario