2009-04-15 16 views
23

tengo varias preguntas relativas a la aplicación mmap en sistemas Linux que no parecen estar muy documentado:Linux MMAP partes internas

Al asignar un archivo a la memoria utilizando mmap, ¿cómo manejar la obtención previa de los datos en tales ¿archivo?

I.e. ¿Qué sucede cuando lees datos de la región mmaped? ¿Los datos se movieron a los cachés L1/L2? ¿Se lee directamente desde el caché de disco? ¿Funcionan el prefetchnta y las instrucciones ASM similares en las zonas ed mmap?

¿Cuál es la sobrecarga de la llamada real mmap? ¿Es relativo a la cantidad de datos asignados, o constante?

Espero que alguien tenga una idea de esto. Gracias por adelantado.

Respuesta

29

mmap es básicamente el acceso programático al subsistema de memoria virtual.

Cuando tiene, por ejemplo, un archivo 1G, y lo mapea, obtiene un puntero a "todo el archivo" como si estuviera en la memoria.

Sin embargo, en este momento no ha sucedido nada excepto la operación de asignación real de reservar páginas para el archivo en la máquina virtual. (Cuanto mayor sea el archivo, más larga será la operación de mapeo, por supuesto).

Para comenzar a leer datos del archivo, simplemente acceda a través del puntero que se le devolvió en la llamada a mmap.

Si desea "precargar" partes del archivo, simplemente visite el área que desea cargar. Asegúrese de visitar TODAS las páginas que desea cargar, ya que la VM solo cargará las páginas a las que acceda. Por ejemplo, digamos dentro de su archivo 1G, tiene un área de "índice" de 10 MB en la que le gustaría asignar. La manera más sencilla sería simplemente "recorrer su índice", o cualquier estructura de datos que tenga, dejando que la página VM en datos según sea necesario. O bien, si "sabe" que son los "primeros 10MB" del archivo, y que el tamaño de su página para su máquina virtual es, digamos, 4K, entonces puede simplemente convertir el puntero mmap en un puntero de char, y simplemente iterar a través del páginas.

void load_mmap(char *mmapPtr) { 
    // We'll load 10MB of data from mmap 
    int offset = 0; 
    for(int offset = 0; offset < 10 * 1024 * 1024; offset += 4 * 1024) { 
     char *p = mmapPtr + offset; 
     // deref pointer to force mmap load 
     char c = *p; 
    } 
} 

En cuanto a cachés L1 y L2, mmap no tiene nada que ver con eso, eso es todo acerca de cómo se accede a los datos.

Dado que está utilizando el sistema VM subyacente, todo lo que resuelva los datos dentro del bloque mmap'd funcionará (desde el ensamblaje).

Si no cambia ninguno de los datos de mmap, la máquina virtual eliminará automáticamente las páginas antiguas a medida que se necesiten nuevas páginas. Si realmente las cambia, la máquina virtual las volverá a escribir.

+8

No sería char "c = p *" ser optimizado de distancia? ¿Debería c declararse volátil? –

+1

En versiones recientes de Linux, puede establecer MAP_POPULATE en el argumento flags en mmap() y las páginas se extraerán antes de que la llamada regrese. Esto bloqueará la llamada durante un período de tiempo que es una función del tamaño del archivo, por lo que ejecutar la función load_mmap() de ejemplo en un subproceso separado mejoraría el rendimiento si hay otro trabajo que pueda realizarse en paralelo antes de que el contenido del archivo lo necesite para ser leído, especialmente porque la mayor parte del trabajo se realiza en el lado del kernel. –

+0

¿'mlock' no precarga las páginas? –

3

No tiene nada que ver con las memorias caché de la CPU; lo mapea en el espacio de direcciones virtuales, y si posteriormente se accede o se bloquea con mlock(), entonces lo trae físicamente a la memoria. En qué CPU está o no almacenada la memoria caché no es nada de lo que realmente tenga control (al menos, no a través de mmap).

Normalmente, es necesario hacer un mapeo para tocar las páginas, pero si hace un mlock o mlockall, eso tendría el mismo efecto (generalmente son privilegiados).

Por lo que respecta a la sobrecarga, realmente no sé, tendrías que medirlo. Supongo que un mmap() que no carga páginas es más o menos una operación de tiempo constante, pero traer las páginas tomará más tiempo con más páginas.

Las versiones recientes de Linux también soportan una MAP_POPULATE bandera que indica a mmap para cargar las páginas en forma inmediata (presumiblemente sólo si es posible)

2

Responder a la pregunta del Sr. Ravi Phulsundar:

Múltiples procesos pueden asignar el mismo archivo siempre y cuando los permisos estén establecidos correctamente. En cuanto a la página del manual de mmap sólo tiene que pasar la bandera MAP_SHARED (si es necesario asignar una muy amplia utilización mmap2 archivo en lugar):

mmap

MAP_SHARED

Compartir esta asignación con todos los demás procesos que mapear este objeto Almacenar en la región es equivalente a escribir en el archivo. El archivo no puede realmente actualizarse hasta que se llame a msync (2) o munmap (2).

0

que utilizan MAP_SHARED