Un archivo mapeado en memoria es un segmento de memoria virtual [1] al que se le ha asignado una correlación directa byte por byte con alguna parte de un archivo o recurso similar a un archivo. Este recurso suele ser un archivo que está físicamente presente en el disco, pero también puede ser un dispositivo, un objeto de memoria compartida u otro recurso al que el sistema operativo puede hacer referencia a través de un descriptor de archivo . Una vez presente, esta correlación entre el archivo y el espacio de la memoria permite que las aplicaciones traten la porción mapeada como si fuera la memoria primaria.
Historia
TOPS-20 PMAP
Uno de los primeros ( c. 1969 ) [2] aplicación de esto fue la PMAP llamada al sistema en el DEC-20 's TOPS-20 sistema operativo, [3] una función utilizada por la empresa de informática del sistema de base de datos del Sistema-1022 . [4]
SunOS 4 mmap
SunOS 4 [5] introdujo Unix 's mmap
, lo que permitió programas 'para asignar los archivos en la memoria.' [1]
Archivos de Windows Growable Memory-Mapped (GMMF)
Dos décadas después del lanzamiento de PMAP de TOPS-20, Windows NT recibió archivos mapeados en memoria de crecimiento (GMMF).
Dado que "la CreateFileMapping
función requiere que se le pase un tamaño" y no es fácil modificar el tamaño de un archivo, se desarrolló una API de GMMF. [6] El uso de GMMF requiere declarar el máximo al que puede crecer el tamaño del archivo, pero no se desperdicia espacio no utilizado.
Beneficios
El beneficio de la asignación de memoria a un archivo es aumentar el rendimiento de E / S, especialmente cuando se usa en archivos grandes. Para archivos pequeños, los archivos mapeados en memoria pueden resultar en una pérdida de espacio libre [7] ya que los mapas de memoria siempre están alineados con el tamaño de la página, que en su mayoría es de 4 KiB. Por lo tanto, un archivo de 5 KiB asignará 8 KiB y, por lo tanto, se desperdiciarán 3 KiB. El acceso a los archivos asignados en memoria es más rápido que el uso de operaciones directas de lectura y escritura por dos razones. En primer lugar, una llamada al sistema es órdenes de magnitud más lenta que un simple cambio en la memoria local de un programa. En segundo lugar, en la mayoría de los sistemas operativos, la región de memoria asignada en realidad es la caché de página del kernel (caché de archivos), lo que significa que no es necesario crear copias en el espacio del usuario.
Ciertas operaciones de archivos mapeados en memoria a nivel de aplicación también funcionan mejor que sus contrapartes de archivos físicos. Las aplicaciones pueden acceder y actualizar los datos en el archivo directamente e in situ, en lugar de buscar desde el principio del archivo o reescribir todo el contenido editado en una ubicación temporal. Dado que el archivo mapeado en memoria se maneja internamente en páginas, el acceso lineal al archivo (como se ve, por ejemplo, en el almacenamiento de datos de archivo plano o en los archivos de configuración) requiere acceso al disco solo cuando se cruza un nuevo límite de página, y puede escribir secciones más grandes del archivo. archivo a disco en una sola operación.
Un posible beneficio de los archivos mapeados en memoria es una "carga diferida", por lo que se utilizan pequeñas cantidades de RAM incluso para un archivo muy grande. Intentar cargar todo el contenido de un archivo que es significativamente mayor que la cantidad de memoria disponible puede causar severa paliza como el sistema operativo lee desde el disco a la memoria y al mismo tiempo escribe páginas de vuelta la memoria al disco. La asignación de memoria no solo puede omitir el archivo de página por completo, sino que también permite que se carguen secciones de tamaño de página más pequeñas a medida que se editan los datos, de manera similar a la paginación de demanda que se usa para los programas.
El proceso de mapeo de memoria lo maneja el administrador de memoria virtual , que es el mismo subsistema responsable de manejar el archivo de paginación . Los archivos asignados en memoria se cargan en la memoria una página completa a la vez. El tamaño de la página lo selecciona el sistema operativo para obtener el máximo rendimiento. Dado que la administración de archivos de página es uno de los elementos más críticos de un sistema de memoria virtual, cargar secciones del tamaño de una página de un archivo en la memoria física es típicamente una función del sistema muy optimizada. [8]
Tipos
Hay dos tipos de archivos asignados en memoria:
Persistido
Los archivos persistentes están asociados con un archivo de origen en un disco. Los datos se guardan en el archivo de origen en el disco una vez finalizado el último proceso. Estos archivos asignados en memoria son adecuados para trabajar con archivos de origen extremadamente grandes. [9]
No persistente
Los archivos no persistentes no están asociados con un archivo en un disco. Cuando el último proceso ha terminado de trabajar con el archivo, los datos se pierden. Estos archivos son adecuados para crear memoria compartida para comunicaciones entre procesos (IPC). [9]
Inconvenientes
La principal razón para elegir la E / S de archivos mapeados en memoria es el rendimiento. Sin embargo, puede haber compensaciones. El enfoque de E / S estándar es costoso debido a la sobrecarga de llamadas al sistema y la copia de memoria. El método de asignación de memoria tiene su costo en fallas de página menores, cuando un bloque de datos se carga en la caché de la página , pero aún no se asigna al espacio de memoria virtual del proceso. En algunas circunstancias, la E / S de archivos mapeados en memoria puede ser sustancialmente más lenta que la E / S de archivos estándar. [10]
Otro inconveniente de los archivos mapeados en memoria se relaciona con el espacio de direcciones de una arquitectura determinada : un archivo más grande que el espacio direccionable solo puede tener partes mapeadas a la vez, lo que complica su lectura. Por ejemplo, una arquitectura de 32 bits como el IA-32 de Intel solo puede abordar directamente 4 GiB o porciones más pequeñas de archivos. Hay una cantidad aún menor de espacio direccionable disponible para programas individuales, generalmente en el rango de 2 a 3 GiB, dependiendo del kernel del sistema operativo. Sin embargo, este inconveniente prácticamente se elimina en la arquitectura moderna de 64 bits .
mmap también tiende a ser menos escalable que los medios estándar de E / S de archivos, ya que muchos sistemas operativos, incluido Linux, tienen un límite en la cantidad de núcleos que manejan fallas de página. Los dispositivos extremadamente rápidos, como los modernos SSD NVM Express , son capaces de convertir los gastos generales en una preocupación real. [11]
Los errores de E / S en el archivo subyacente (por ejemplo, su unidad extraíble está desconectada o el medio óptico se expulsa, el disco está lleno al escribir, etc.) mientras se accede a su memoria asignada se informa a la aplicación como señales SIGSEGV / SIGBUS en POSIX, y el Excepción estructurada EXECUTE_IN_PAGE_ERROR en Windows. Todo código que acceda a la memoria mapeada debe estar preparado para manejar estos errores, que normalmente no ocurren al acceder a la memoria.
Solo las arquitecturas de hardware con una MMU pueden admitir archivos asignados en memoria. En arquitecturas sin una MMU, el sistema operativo puede copiar todo el archivo en la memoria cuando se realiza la solicitud para mapearlo, pero esto es extremadamente inútil y lento si solo se accederá a una pequeña parte del archivo, y solo puede funcionar para archivos que quepa en la memoria disponible.
Usos comunes
Quizás el uso más común de un archivo mapeado en memoria es el cargador de procesos en la mayoría de los sistemas operativos modernos (incluidos Microsoft Windows y sistemas similares a Unix). Cuando se inicia un proceso , el sistema operativo usa un archivo mapeado en memoria para traer el archivo ejecutable , junto con los módulos cargables, en la memoria para su ejecución. La mayoría de los sistemas de mapeo de memoria utilizan una técnica llamada paginación por demanda , en la que el archivo se carga en la memoria física en subconjuntos (una página cada uno) y solo cuando se hace referencia a esa página. [12] En el caso específico de archivos ejecutables, esto permite que el sistema operativo cargue selectivamente solo aquellas partes de una imagen de proceso que realmente necesitan ejecutarse.
Otro uso común de los archivos asignados en memoria es compartir memoria entre múltiples procesos. En los sistemas operativos modernos en modo protegido , generalmente no se permite que los procesos accedan al espacio de memoria asignado para su uso por otro proceso. (El intento de un programa de hacerlo provoca fallas en las páginas no válidas o violaciones de segmentación ). Hay varias técnicas disponibles para compartir la memoria de manera segura, y la E / S de archivos mapeados en memoria es una de las más populares. Dos o más aplicaciones pueden mapear simultáneamente un solo archivo físico en la memoria y acceder a esta memoria. Por ejemplo, el sistema operativo Microsoft Windows proporciona un mecanismo para que las aplicaciones mapeen en memoria un segmento compartido del archivo de página del sistema y compartan datos a través de esta sección.
Soporte de plataforma
La mayoría de los sistemas operativos o entornos de ejecución modernos admiten alguna forma de acceso a archivos asignados en memoria. La función mmap () , [13] que crea un mapeo de un archivo dado un descriptor de archivo, una ubicación de inicio en el archivo y una longitud, es parte de la especificación POSIX , por lo que la amplia variedad de sistemas compatibles con POSIX, como UNIX , Linux , Mac OS X [14] u OpenVMS , admiten un mecanismo común para archivos de asignación de memoria. Los sistemas operativos Microsoft Windows también admiten un grupo de funciones API para este propósito, como CreateFileMapping () . [15]
Algunas implementaciones portátiles gratuitas de archivos mapeados en memoria para Microsoft Windows y plataformas compatibles con POSIX son:
- Boost.Interprocess, [16] en Bibliotecas Boost C ++
- Boost.Iostreams, [17] también en Bibliotecas Boost C ++
- Fmstream [18]
- Cpp-mmf [19]
El lenguaje de programación Java proporciona clases y métodos para acceder a archivos mapeados en memoria, como FileChannel
.
El lenguaje de programación D admite archivos mapeados en memoria en su biblioteca estándar (módulo std.mmfile). [20]
Ruby tiene una gema (biblioteca) llamada Mmap, que implementa objetos de archivo asignados en memoria.
Desde la versión 1.6, Python ha incluido un módulo mmap en su biblioteca estándar. [21] Los detalles del módulo varían según si la plataforma de host es Windows o similar a Unix .
Para Perl hay varios módulos disponibles para archivos de mapeo de memoria en el CPAN , como Sys :: Mmap [22] y Archivo :: Mapa . [23]
En el tiempo de ejecución de Microsoft .NET, P / Invoke se puede usar para usar archivos mapeados en memoria directamente a través de la API de Windows . El acceso administrado (no es necesario P / Invoke) a los archivos asignados en memoria se introdujo en la versión 4 del tiempo de ejecución (consulte Archivos asignados en memoria ). Para versiones anteriores, existen bibliotecas de terceros que proporcionan API administradas. [24]
PHP admitió técnicas de mapeo de memoria en una serie de funciones nativas de acceso a archivos como file_get_contents () pero lo ha eliminado en 5.3 (ver registro de revisión ).
Para el lenguaje de programación R existe una biblioteca en CRAN llamada bigmemory que usa la biblioteca Boost y proporciona matrices respaldadas en memoria mapeada directamente en R. El paquete ff ofrece vectores, matrices, matrices y marcos de datos mapeados en memoria.
El lenguaje de programación J ha admitido archivos mapeados en memoria desde al menos 2005. Incluye soporte para datos de matriz en caja y archivos de tipos de datos únicos. El soporte se puede cargar desde 'data / jmf' Los motores de base de datos Jdb y JD de J utilizan archivos mapeados en memoria para almacenes de columnas.
Referencias
- ↑ a b Chris Siebenmann (7 de junio de 2018). "La historia del confuso conjunto de formas de bajo nivel de Unix para asignar memoria" .
- ^ El desarrollo comenzó en 1969, enviado en 1976
- ^ "Manual de referencia de llamadas del monitor TOPS-20" (PDF) .
- ^ "Sistema de base de datos System 1022" .
Teníamos una caché PMAP para E / S de archivos (como PA1050) en secciones extendidas.
- ^ Diciembre de 1988
- ^ Jeffrey Richter (octubre de 1995). "Agregue archivos mapeados en memoria de crecimiento a su aplicación". Revista de sistemas de Microsoft . págs. 17-28.
- ^ "Copia archivada" . Archivado desde el original el 7 de agosto de 2011 . Consultado el 21 de mayo de 2011 .CS1 maint: copia archivada como título ( enlace )
- ^ , "¿Qué tienen que ofrecer los archivos asignados en memoria?".
- ^ a b "Archivos asignados en memoria" . Red de desarrolladores de Microsoft . Consultado el 4 de enero de 2016 .
- ^ http://lists.freebsd.org/pipermail/freebsd-questions/2004-June/050371.html , lectura frente a mmap (o io frente a fallas de página) por Matthew Dillon
- ^ Papagiannis, Anastasios; Xanthakis, Giorgos; Saloustros, Giorgos; Marazakis, Manolis; Bilas, Angelos (2020). Optimización de E / S asignadas en memoria para dispositivos de almacenamiento rápido . USENIX ATC '20. págs. 813–827.
- ^ "Búsqueda de demanda"
- ^ Archivos asignados en memoria archivados el 9 de febrero de 2007 en la Wayback Machine.
- ^ Apple - Mac OS X Leopard - Tecnología - UNIX Archivado el 23 de abril de 2009 en Wayback Machine.
- ^ Función CreateFileMapping (Windows)
- ^ "Compartir memoria entre procesos: archivos mapeados en memoria" . Boost.org.
- ^ "Archivos asignados en memoria" . Boost.org.
- ^ "Archivos asignados en memoria para sistemas Windows y POSIX" . SourceForge.
- ^ "cpp-mmf" . GitHub.
- ^ "std.mmfile - Lenguaje de programación D" . Marte digital . Consultado el 4 de diciembre de 2011 .
- ^ "Nuevos módulos en 1.6" . Archivado desde el original el 30 de diciembre de 2006 . Consultado el 23 de diciembre de 2008 .
- ^ "Sys :: Módulo Perl Mmap" .
- ^ "Archivo :: Módulo Map Perl" .
- ^ DotNet Archivado el 19 de abril de 2010 en Wayback Machine.