mmap () vs. bloques de lectura


Estoy trabajando en un programa que procesará archivos que potencialmente podrían ser de 100 GB o más de tamaño. Los archivos contienen conjuntos de registros de longitud variable. Tengo una primera implementación en marcha y ahora estoy buscando mejorar el rendimiento, particularmente en hacer E/S de manera más eficiente, ya que el archivo de entrada se escanea muchas veces.

¿Hay una regla general para usar mmap() versus leer en bloques a través de la biblioteca fstream de C++? Lo que me gustaría hacer es leer grandes bloques de coloque el disco en un búfer, procese los registros completos desde el búfer y luego lea más.

El código mmap() podría potencialmente ser muy desordenado ya que los bloques mmap'd necesitan estar en los límites del tamaño de la página (según mi entendimiento) y los registros podrían potencialmente gustar a través de los límites de la página. Con fstreams, solo puedo buscar el inicio de un registro y comenzar a leer de nuevo, ya que no estamos limitados a leer bloques que se encuentran en los límites del tamaño de la página.

¿Cómo puedo decidir entre estas dos opciones sin ¿realmente escribir una implementación completa primero? ¿Alguna regla empírica (por ejemplo, mmap() es 2 veces más rápida) o pruebas simples?

Author: isomorphismes, 2008-09-05

12 answers

Estaba tratando de encontrar la última palabra sobre el rendimiento de mmap / read en Linux y me encontré con un buen post ( link) en la lista de correo del kernel de Linux. Es de 2000, por lo que ha habido muchas mejoras en IO y memoria virtual en el núcleo desde entonces, pero explica muy bien la razón por la que mmap o read podría ser más rápido o más lento.

  • Una llamada a mmap tiene más sobrecarga que read (al igual que epoll tiene más sobrecarga que poll, que tiene más sobrecarga que read). Cambiar las asignaciones de memoria virtual es una operación bastante costosa en algunos procesadores por las mismas razones que cambiar entre diferentes procesos es costoso.
  • El sistema IO ya puede usar la caché del disco, por lo que si lee un archivo, llegará a la caché o la perderá sin importar el método que use.

Sin embargo,

  • Los mapas de memoria son generalmente más rápidos para el acceso aleatorio, especialmente si sus patrones de acceso son escasos e impredecibles.
  • Mapas de memoria le permite mantener usando páginas de la caché hasta que haya terminado. Esto significa que si usa un archivo en gran medida durante un largo período de tiempo, luego lo cierra y lo vuelve a abrir, las páginas seguirán almacenadas en caché. Con read, su archivo puede haber sido limpiado de la caché hace mucho tiempo. Esto no se aplica si utiliza un archivo y lo descarta inmediatamente. (Si intenta mlock páginas solo para mantenerlos en caché, está tratando de ser más inteligente que la caché de disco y este tipo de tonterías rara vez ayuda al sistema rendimiento).
  • Leer un archivo directamente es muy simple y rápido.

La discusión de mmap / read me recuerda a otras dos discusiones de rendimiento:

  • Algunos programadores de Java se sorprendieron al descubrir que las E/S sin bloqueo a menudo son más lentas que las E/S bloqueadas, lo que tenía perfecto sentido si sabes que las E/S sin bloqueo requieren hacer más llamadas de sistema.

  • Algunos otros programadores de red se sorprendieron al saber que epoll es a menudo más lento que poll, lo cual tiene mucho sentido si sabes que administrar epoll requiere hacer más syscalls.

Conclusión: Utilice mapas de memoria si accede a datos aleatoriamente, manténgalos durante mucho tiempo, o si sabe que puede compartirlos con otros procesos (MAP_SHARED no es muy interesante si no hay intercambio real). Lea los archivos normalmente si accede a los datos secuencialmente o los descarta después de la lectura. Y si cualquiera de los métodos hace que su programa sea menos complejo, haga que. Para muchos casos del mundo real no hay una manera segura de demostrar que uno es más rápido sin probar su aplicación real y NO un punto de referencia.

(Lo siento por necro'ing esta pregunta, pero yo estaba buscando una respuesta y esta pregunta siguió apareciendo en la parte superior de los resultados de Google.)

 160
Author: Dietrich Epp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-02 21:13:50

El costo principal de rendimiento será la e/s de disco. "mmap()" es ciertamente más rápido que istream, pero la diferencia podría no ser notable porque la e/s de disco dominará sus tiempos de ejecución.

Probé el fragmento de código de Ben Collins (ver arriba/abajo) para probar su afirmación de que "mmap() es mucho más rápido" y no encontré ninguna diferencia medible. Ver mis comentarios sobre su respuesta.

Ciertamente no recomendaría por separado mmap'ing cada registro por turno a menos que su los "registros" son enormes - eso sería terriblemente lento, requiriendo 2 llamadas al sistema para cada registro y posiblemente perdiendo la página de la memoria caché del disco.....

En tu caso creo que mmap(), istream y las llamadas open()/read() de bajo nivel serán todas iguales. Yo recomendaría mmap () en estos casos:

  1. Hay acceso aleatorio (no secuencial) dentro del archivo, Y
  2. todo encaja cómodamente en la memoria O hay localidad de referencia dentro del archivo, por lo que que ciertas páginas pueden ser mapeadas y otras páginas mapeadas. De esta manera, el sistema operativo utiliza la RAM disponible para obtener el máximo beneficio.
  3. O si varios procesos están leyendo/trabajando en el mismo archivo, entonces mmap() es fantástico porque todos los procesos comparten las mismas páginas físicas.

(por cierto - Me encanta mmap () / MapViewOfFile ()).

 42
Author: Tim Cooper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-30 18:45:49

Mmap es camino más rápido. Puedes escribir un punto de referencia simple para demostrártelo a ti mismo:

char data[0x1000];
std::ifstream in("file.bin");

while (in)
{
  in.read(data, 0x1000);
  // do something with data
}

Versus:

const int file_size=something;
const int page_size=0x1000;
int off=0;
void *data;

int fd = open("filename.bin", O_RDONLY);

while (off < file_size)
{
  data = mmap(NULL, page_size, PROT_READ, 0, fd, off);
  // do stuff with data
  munmap(data, page_size);
  off += page_size;
}

Claramente, estoy omitiendo detalles (como cómo determinar cuándo llegas al final del archivo en el caso de que tu archivo no sea un múltiplo de page_size, por ejemplo), pero realmente no debería ser mucho más complicado que esto.

Si puede, puede intentar dividir sus datos en varios archivos que pueden ser mmap () - ed en su totalidad en lugar de en parte (mucho más simple).

Hace un par de meses tuve una implementación a medias de una clase de flujo mmap ()-ed de ventana deslizante para boost_iostreams, pero a nadie le importó y me ocupé de otras cosas. Desafortunadamente, eliminé un archivo de viejos proyectos inacabados hace unas semanas, y esa fue una de las víctimas : - (

Actualización: También debería agregar la advertencia de que este punto de referencia se vería bastante diferente en Windows porque Microsoft implementó una caché de archivos ingeniosa eso hace la mayor parte de lo que haría con mmap en primer lugar. Es decir, para los archivos de acceso frecuente, solo podría hacer std:: ifstream.read () y sería tan rápido como mmap, porque la caché de archivos ya habría hecho un mapeo de memoria para usted, y es transparente.

Final Update : Miren, gente: a través de muchas combinaciones de plataformas diferentes de sistemas operativos y bibliotecas estándar y discos y jerarquías de memoria, no puedo decir con certeza que la llamada al sistema mmap, vista como una caja negra, siempre siempre siempre será sustancialmente más rápido que read. Esa no era exactamente mi intención, incluso si mis palabras pudieran interpretarse de esa manera. En última instancia, mi punto era que la e/s mapeada en memoria es generalmente más rápida que la e/s basada en bytes; esto sigue siendo cierto. Si encuentra experimentalmente que no hay diferencia entre los dos, entonces la única explicación que me parece razonable es que su plataforma implementa el mapeo de memoria debajo de las cubiertas de una manera que es ventajosa para la ejecución de llamadas a read. La única manera de estar absolutamente seguro de que está utilizando e/s mapeadas en memoria de una manera portátil es usar mmap. Si no le importa la portabilidad y puede confiar en las características particulares de sus plataformas de destino, entonces usar read puede ser adecuado sin sacrificar mensurablemente ningún rendimiento.

Editar para limpiar la lista de respuestas: @jbl:

La ventana deslizante mmap suena Interesante.... ¿Puedes decir un poco más ¿sobre eso?

Claro - Estaba escribiendo una biblioteca de C++ para Git (un libgit++, si se quiere), y me encontré con un problema similar a este: necesitaba poder abrir archivos grandes (muy grandes) y no tener un rendimiento total (como sería con std::fstream).

Boost::Iostreams ya tiene una fuente mapped_file, pero el problema era que era mmapping archivos completos, lo que limita a 2^(wordsize). En máquinas de 32 bits, 4GB no es lo suficientemente grande. No es irrazonable esperar tener .pack archivos en Git que se vuelven mucho más grandes que eso, por lo que necesitaba leer el archivo en trozos sin recurrir a la e/s de archivo normal. Bajo las cubiertas de Boost::Iostreams, implementé un Código Fuente, que es más o menos otra vista de la interacción entre std::streambuf y std::istream. También podría intentar un enfoque similar simplemente heredando std::filebuf en un mapped_filebuf y de manera similar, heredando std::fstream en a mapped_fstream. Es la interacción entre los dos lo que es difícil de hacer bien. Boost::Iostreams ha hecho algo de la obra para usted, y también proporciona ganchos para filtros y cadenas, por lo que pensé que sería más útil implementarlo de esa manera.

 42
Author: Ben Collins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-04 04:01:50

Ya hay muchas buenas respuestas aquí que cubren muchos de los puntos más destacados, así que solo agregaré un par de problemas que no vi abordados directamente arriba. Es decir, esta respuesta no debe considerarse una completa de los pros y los contras, sino más bien una adición a otras respuestas aquí.

Mmap parece mágico

Tomando el caso donde el archivo ya está completamente almacenado en caché1 como base de referencia2, mmap podría parecer más o menos como magia :

  1. mmap solo requiere 1 llamada al sistema para (potencialmente) asignar todo el archivo, después de lo cual no se necesitan más llamadas al sistema.
  2. mmap no requiere una copia de los datos del archivo del núcleo al espacio de usuario.
  3. mmap le permite acceder al archivo "como memoria", incluido el procesamiento con cualquier truco avanzado que pueda hacer contra la memoria, como la auto-vectorización del compilador, SIMD intrínsecos, prefetching, análisis optimizado en memoria rutinas, OpenMP, etc.

En el caso de que el archivo ya esté en la caché, parece imposible de superar: simplemente accede directamente a la caché de la página del kernel como memoria y no puede ser más rápido que eso.

Bueno, puede.

Mmap no es realmente mágico porque...

Mmap todavía hace trabajo por página

Un costo oculto primario de mmap vs read(2) (que es realmente el nivel de sistema operativo comparable syscall para bloques de lectura ) es que con mmap tendrá que hacer "algún trabajo" para cada página 4K en el espacio de usuario, a pesar de que podría estar oculto por el mecanismo de error de página.

Por ejemplo, una implementación típica que solo mmaps todo el archivo tendrá que fallar, por lo que 100 GB / 4K = 25 millones de fallos para leer un archivo de 100 GB. Ahora, estos serán fallos menores, pero 25 mil millones de fallas de página todavía no va a ser súper rápido. El costo de una falla menor es probablemente en los 100 de nanos en el mejor caso.

Mmap se basa en gran medida en el rendimiento TLB

Ahora, puede pasar MAP_POPULATE a mmap para indicarle que configure todas las tablas de páginas antes de regresar, por lo que no debería haber errores de página al acceder a ella. Ahora, esto tiene el pequeño problema de que también lee todo el archivo en RAM, que va a explotar si intentas mapear un archivo de 100 GB, pero ignorémoslo por ahora3. El kernel necesita hacer trabajo por página para configurar estas tablas de página (se muestra como kernel tiempo). Esto termina siendo un costo importante en el enfoque mmap, y es proporcional al tamaño del archivo (es decir, no se vuelve relativamente menos importante a medida que crece el tamaño del archivo)4.

Finalmente, incluso en el espacio de usuario acceder a tal asignación no es exactamente libre (en comparación con los grandes búferes de memoria que no se originan desde un mmap basado en archivos)-incluso una vez que se configuran las tablas de páginas, cada acceso a una nueva página va a, conceptualmente, incurrir en un error TLB. Dado que mmap ing un archivo significa usar el caché de página y sus páginas 4K, de nuevo incurre en este costo 25 millones de veces para un archivo de 100 GB.

Ahora, el costo real de estos errores de TLB depende en gran medida de al menos los siguientes aspectos de su hardware: (a) cuántos TLB enties 4K tiene y cómo funciona el resto del almacenamiento en caché de traducción (b) qué tan bien se maneja el prefetch de hardware con el TLB - por ejemplo, ¿puede el prefetch desencadenar una página? (c) cuán rápido y cuán paralelo es el hardware para caminar páginas. En la moderna Intel x86 de gama alta en general, el hardware para caminar páginas es muy fuerte: hay al menos 2 caminadores de páginas paralelos, una caminata de página puede ocurrir simultáneamente con la ejecución continua, y la prefetching de hardware puede desencadenar una caminata de página. Por lo tanto, el impacto de TLB en una carga de lectura de streaming es bastante bajo, y tal carga a menudo funcionará de manera similar independientemente del tamaño de la página. Otro hardware es generalmente mucho peor, sin embargo!

Read () evita estas trampas

El read() syscall, que es lo que generalmente subyace a las llamadas de tipo" block read " ofrecidas, por ejemplo, en C, C++ y otros lenguajes, tiene una desventaja principal de la que todos son conscientes:

  • Cada llamada read() de N bytes debe copiar N bytes del núcleo al espacio de usuario.

Por otro lado, evita la mayoría de los costos anteriores: no necesita mapear 25 millones de páginas 4K en espacio de uso. Por lo general, puede malloc un solo búfer pequeño búfer en el espacio del usuario, y reutilizar eso repetidamente para todos tus read llamadas. En el lado del kernel, casi no hay ningún problema con páginas 4K o errores de TLB porque toda la RAM generalmente se mapea linealmente usando unas pocas páginas muy grandes (por ejemplo, páginas de 1 GB en x86), por lo que las páginas subyacentes en la caché de páginas se cubren de manera muy eficiente en el espacio del kernel.

Así que básicamente tienes la siguiente comparación para determinar cuál es más rápido para una sola lectura de un archivo grande:

Es más costoso el trabajo extra por página que implica el enfoque mmap que el trabajo por byte de copiar el contenido del archivo desde el núcleo al espacio de usuario implícito mediante el uso de read()?

En muchos sistemas, en realidad están aproximadamente equilibrados. Tenga en cuenta que cada uno se escala con atributos completamente diferentes del hardware y la pila del sistema operativo.

En particular, el enfoque mmap se vuelve relativamente más rápido cuando:

  • El sistema operativo tiene un manejo rápido de fallas menores y especialmente optimizaciones de carga de fallas menores, tales como fallas.
  • El sistema operativo tiene una buena implementación MAP_POPULATE que puede procesar eficientemente mapas grandes en casos donde, por ejemplo, las páginas subyacentes son contiguas en memoria física.
  • El hardware tiene un fuerte rendimiento de traducción de páginas, como TLBS grandes, TLBs rápidos de segundo nivel, caminadores de páginas rápidos y paralelos, buena interacción de prefetch con la traducción y así sucesivamente.

... mientras que el acercamiento read() se vuelve relativamente más rápido cuando:

  • El read() syscall tiene una buena copia rendimiento. Por ejemplo, buen rendimiento copy_to_user en el lado del kernel.
  • El núcleo tiene una manera eficiente (en relación con el usuario) de mapear la memoria, por ejemplo, usando solo unas pocas páginas grandes con soporte de hardware.
  • El núcleo tiene syscalls rápidos y una forma de mantener las entradas TLB del núcleo a través de syscalls.

Los factores de hardware anteriores varían enormemente entre diferentes plataformas, incluso dentro de la misma familia (por ejemplo, dentro de las generaciones x86 y especialmente los segmentos de mercado) y definitivamente a través de arquitecturas (por ejemplo, ARM vs x86 vs PPC).

Los factores del sistema operativo también siguen cambiando, con varias mejoras en ambos lados que causan un gran salto en la velocidad relativa para un enfoque u otro. Una lista reciente incluye:

  • Adición de falla-alrededor, descrito anteriormente, que realmente ayuda al caso mmap sin MAP_POPULATE.
  • Adición de métodos de ruta rápida copy_to_user en arch/x86/lib/copy_user_64.S, por ejemplo, usando REP MOVQ cuando es rápido, que realmente ayudan a la read() caso.

1 Esto más o menos también incluye el caso en el que el archivo no se almacenó completamente en caché para empezar, pero donde la lectura anticipada del sistema operativo es lo suficientemente buena como para que parezca así (es decir, la página generalmente se almacena en caché cuando lo desea). Sin embargo, este es un problema sutil porque la forma en que funciona la lectura anticipada a menudo es bastante diferente entre las llamadas mmap y read, y se puede ajustar aún más mediante llamadas "advise" como se describe en 2.

2 ... porque si el archivo está no almacenado en caché, su comportamiento estará completamente dominado por las preocupaciones de E / s, incluida la simpatía de su patrón de acceso con el hardware subyacente, y todo su esfuerzo debe estar en garantizar que dicho acceso sea lo más comprensivo posible, por ejemplo, mediante el uso de madvise o fadvise llamadas (y cualquier cambio de nivel de aplicación que pueda realizar para mejorar los patrones de acceso).

3 Podrías evitar eso, por ejemplo, secuencialmente mmap ing en windows de un tamaño más pequeño, digamos 100 MB.

4 De hecho, resulta que el enfoque MAP_POPULATE es (al menos una combinación hardware/sistema operativo) solo un poco más rápido que no usarlo, probablemente porque el núcleo está usando faultaround - por lo que el número real de fallas menores se reduce en un factor de 16 aproximadamente.

 22
Author: BeeOnRope,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-26 02:55:38

Siento que Ben Collins haya perdido su código fuente mmap de ventanas corredizas. Eso sería bueno para tener en Impulso.

Sí, mapear el archivo es mucho más rápido. Esencialmente, está utilizando el subsistema de memoria virtual del sistema operativo para asociar la memoria al disco y viceversa. Piénselo de esta manera: si los desarrolladores del kernel del sistema operativo pudieran hacerlo más rápido, lo harían. Porque hacerlo hace que casi todo sea más rápido: bases de datos, tiempos de arranque, tiempos de carga de programas, etc.

El enfoque de la ventana deslizante realmente no es tan difícil ya que se pueden mapear varias páginas contiguas a la vez. Por lo tanto, el tamaño del registro no importa siempre y cuando el más grande de cualquier registro individual quepa en la memoria. Lo importante es gestionar la contabilidad.

Si un registro no comienza en un límite de getpagesize (), la asignación debe comenzar en la página anterior. La longitud de la región mapeada se extiende desde el primer byte del registro (redondeado hacia abajo si es necesario al múltiplo más cercano de getpagesize()) hasta último byte del registro (redondeado al múltiplo más cercano de getpagesize ()). Cuando haya terminado de procesar un registro, puede desasignar (), y pasar a la siguiente.

Todo esto funciona bien bajo Windows también usando CreateFileMapping() y MapViewOfFile() (y GetSystemInfo() para obtener SYSTEM_INFO.dwAllocationGranularity --- no SYSTEM_INFO.dwPageSize).

 7
Author: mlbrock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-15 23:09:57

Mmap debería ser más rápido, pero no se cuánto. Depende mucho de tu código. Si utiliza mmap es mejor mmap todo el archivo de una vez, que le hará la vida mucho más fácil. Un problema potencial es que si su archivo es más grande que 4GB (o en la práctica el límite es más bajo, a menudo 2GB) necesitará una arquitectura de 64 bits. Así que si estás usando un entorno 32, probablemente no quieras usarlo.

Dicho esto, puede haber una mejor ruta para mejorar el rendimiento. Dijiste el archivo de entrada se escanea muchas veces, si puede leerlo en una sola pasada y luego terminar con él, que potencialmente podría ser mucho más rápido.

 4
Author: Leon Timmermans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-05 15:11:22

Estoy de acuerdo en que la E/S del archivo mmap va a ser más rápida, pero mientras comparas el código, ¿no debería el ejemplo del contador estar algo optimizado?

Ben Collins escribió:

char data[0x1000];
std::ifstream in("file.bin");

while (in)
{
    in.read(data, 0x1000);
    // do something with data 
}

Yo sugeriría también intentar:

char data[0x1000];
std::ifstream iifle( "file.bin");
std::istream  in( ifile.rdbuf() );

while( in )
{
    in.read( data, 0x1000);
    // do something with data
}

Y más allá de eso, también puede intentar hacer que el tamaño del búfer sea el mismo que una página de memoria virtual, en caso de que 0x1000 no sea el tamaño de una página de memoria virtual en su máquina... IMHO mmap'd archivo E / S todavía gana, pero esto debe hacer las cosas están más cerca.

 3
Author: paxos1977,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-30 05:31:49

Tal vez debería preprocesar los archivos, para que cada registro esté en un archivo separado (o al menos que cada archivo tenga un tamaño compatible con mmap).

También podría hacer todos los pasos de procesamiento para cada registro, antes de pasar al siguiente? ¿Tal vez eso evitaría algo de la sobrecarga de IO?

 2
Author: Douglas Leeder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-05 15:37:26

Recuerdo mapear un archivo enorme que contenía una estructura de árbol en la memoria hace años. Me sorprendió la velocidad en comparación con la deserialización normal que implica mucho trabajo en memoria, como asignar nodos de árbol y establecer punteros. Así que, de hecho, estaba comparando una sola llamada a mmap (o su contraparte en Windows) contra muchas (MUCHAS) llamadas al operador llamadas nuevas y constructoras. Para este tipo de tarea, mmap es inmejorable en comparación con la deserialización. Por supuesto, uno debe mirar en los aumentos puntero reubicable para esto.

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-27 19:18:47

Esto suena como un buen caso de uso para multi-threading... Creo que podrías fácilmente configurar un hilo para leer datos mientras el otro (s) lo procesa. Esa puede ser una manera de aumentar dramáticamente el rendimiento percibido. Sólo una idea.

 1
Author: Pat Notz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-06 13:41:00

En mi opinión, usar mmap() "simplemente" libera al desarrollador de tener que escribir su propio código de caché. En un simple caso de "leer a través del archivo eactly una vez", esto no va a ser difícil (aunque como mlbrock señala que aún guarda la copia de memoria en el espacio de proceso), pero si va y viene en el archivo o omite bits y así sucesivamente, creo que los desarrolladores del núcleo han probablemente hecho un mejor trabajo implementando el almacenamiento en caché que yo...

 1
Author: mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-29 18:02:26

Creo que lo mejor de mmap es el potencial para la lectura asíncrona con:

    addr1 = NULL;
    while( size_left > 0 ) {
        r = min(MMAP_SIZE, size_left);
        addr2 = mmap(NULL, r,
            PROT_READ, MAP_FLAGS,
            0, pos);
        if (addr1 != NULL)
        {
            /* process mmap from prev cycle */
            feed_data(ctx, addr1, MMAP_SIZE);
            munmap(addr1, MMAP_SIZE);
        }
        addr1 = addr2;
        size_left -= r;
        pos += r;
    }
    feed_data(ctx, addr1, r);
    munmap(addr1, r);

El problema es que no puedo encontrar el MAP_FLAGS adecuado para dar una pista de que esta memoria debe sincronizarse desde el archivo lo antes posible. Espero que MAP_POPULATE dé la pista correcta para mmap (es decir, no intentará cargar todo el contenido antes de return from call, sino que lo hará en async. con feed_data). Al menos da mejores resultados con esta bandera incluso que el manual indica que no hace nada sin MAP_PRIVATE desde 2.6.23.

 1
Author: ony,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-04 12:43:48