Rapidez de escritura en archivos: "write" contra "mmap"
20200526173139
La aplicación con
El listado 1 contiene nuestra aplicación que utiliza la función
Para crear el arreglo de caracteres nulos, empleamos la función
Para asegurarnos que el archivo tiene el tamaño deseado antes de mapearlo en memoria, lo abrimos y ejecutamos
Después, mapeamos el archivo en memoria con
El resultado final muestra que la versión de mapeo en memoria es más rápida que la versión que utiliza la función
Rapidez de escritura en archivos: "write" contra "mmap"
Este es un experimento para comparar la velocidad de dos métodos para escribir archivos: mediante la función
El experimento consiste en crear dos programas que escriban un archivo de un tamaño arbitrario llenos con el caracter write
, y mapeando el archivo en la memoria de la aplicación. La segunda podemos hacerla con alguna de las funciones para escribir en memoria (como mset
, o mcpy
) sobre algún archivo mapeado en la memoria de la aplicación con ayuda de mmap
.0x00
(caracter nulo), cada programa con uno de los dos métodos mencionados en el párrafo anterior. Los programas toman dos parámetros de entrada: el nombre del archivo que van a escribir, y la cantidad de mega-bytes que van a escribir en los archivos.
La aplicación con write
El listado 1 contiene nuestra aplicación que utiliza la función write
para escribir el archivo. Llamamos a este archivo write_performance.c
. Su primer argumento de la línea de comandos debe ser la ruta del archivo que va a escribir, tal como lo pide el prototipo de la función open
, y el segundo argumento debe ser un número entero que indique cuántos mega-bytes escribirá sobre el archivo.Para crear el arreglo de caracteres nulos, empleamos la función
calloc
. Y para asegurar que la escritura al archivo haya terminado antes de que finalice el programa, ejecutaremos fsync
. #include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int nargs, char ** argv)
{
int target_file;
char * buffer;
target_file = open(
argv[1],
O_RDWR | O_CREAT,
0666
);
buffer = calloc(
atoi(argv[2]) * 1024 * 1024,
1
);
write(
target_file,
buffer,
atoi(argv[2]) * 1024 * 1024
);
close(target_file);
return 0;
}
Listado 1. Contenido de write_performance.c
.La aplicación con MMAP
El listado 2 contiene nuestra versión del programa que escribe sobre el archivo ahora con funciones que manipulan un espacio de memoria mapeado en el programa.Para asegurarnos que el archivo tiene el tamaño deseado antes de mapearlo en memoria, lo abrimos y ejecutamos
lseek
para colocar el cursor en la última posición del archivo. Una vez en esa posición, ahí escribimos un caracter nulo (y en consecuencia, ahora el archivo tiene el tamaño deseado).Después, mapeamos el archivo en memoria con
mmap
y lo llenamos de caracteres nulos utilizando la función mset
. Para asegurar que las escrituras hayan llegado al archivo antes de que termine el programa, ejecutamos la función msync
. Finalmente, eliminamos el mapa de memoria con munmap
y cerramos el archivo.#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(int nargs, char ** argv)
{
int target_file;
char * map;
target_file = open(
argv[1],
O_RDWR | O_CREAT,
0666
);
lseek(
target_file,
atoi(argv[2]) * 1024 * 1024,
SEEK_SET
);
write(
target_file,
"",
1
);
map = mmap(
0,
atoi(argv[2]) * 1024 * 1024,
PROT_READ | PROT_WRITE,
MAP_SHARED,
target_file,
0
);
memset(
map,
0x00,
atoi(argv[2]) * 1024 * 1024
);
msync(
map,
atoi(argv[2]) * 1024 * 1024,
MS_SYNC
);
munmap(
map,
atoi(argv[2]) * 1024 * 1024
);
close(target_file);
return 0;
}
Listado 2. Contenido de mmap_performance.c
La prueba
Para compilar nuestras aplicaciones, utilizamos los comandos de consola que aparecen en el listado 3. Y para hacer las mediciones de desempeño, ejecutamos los programas dentro del contexto del comandotime
(como lo mostramos en el listado 4).El resultado final muestra que la versión de mapeo en memoria es más rápida que la versión que utiliza la función
write
. El resultado puede variar en cada instancia del proceso. Pero el desempeño de mmap_performance
se mantiene por arriba de write_performance
en aproximadamente 10%.$ gcc ./write_performance.c -o write_performance
$ gcc ./mmap_performance.c -o mmap_performance
Listado 3. Comandos para compilar las aplicaciones write_performance
y mmap_performance
.$ time ./write_performance test_file 1000
real 0m1.343s
user 0m0.106s
sys 0m0.938s
$ time ./mmap_performance testfile 1000
real 0m1.150s
user 0m0.197s
sys 0m0.767s
Listado 4. Medidas de desempeño de los programas write_performance
y mmap_performance
al escribir archivos de 1 GB.
Comentarios
Publicar un comentario