[eside-ghost] Lectura/escritura eficiente de ficheros en C
Pablo Garaizar Sagarminaga
garaizar en eside.deusto.es
Vie Ene 27 09:16:48 CET 2006
Aupa!
El Thu, 26 Jan 2006 15:03:14 -0600
Borja Sotomayor <borja en borjanet.com> comentaba:
> Lo que pasa es que tampoco tenemos muy claro cómo sería esa solución
> "más eficiente" ;-) Por lo que tengo entendido (y corregidme si me
> equivoco), utilizar fprintf/fscanf para manipular ficheros muy
> grandes puede ser poco eficiente, y hay llamadas a más bajo nivel
> para mapear los ficheros directamente a memoria y luego transferir
> datos entre ficheros utilizando memcpy, no? A bote pronto, diria que
> hay que hacerlo con mmap y munmap, pero igual esa no es la mejor
> manera de hacerlo. Me imagino que otra alternativa sería utilizando
> read()/write() a pelo con un tamaño de buffer óptimo.
Usando funciones de la libC, la eficiencia a tan bajo nivel la tienes
que intuir, porque luego te llevas sorpresas al hacer un ltrace y
un strace. Me explico: quizá tu te comas toda la olla para reservar a
base de malloc's la memoria óptima para esa copia en concreto,
compilas, va bien y luego al hacer un ltrace ves que ese malloc se ha
convertido en un mmap por lo que sea.
A mi modo de ver, a la vez que mapear todo el fichero en memoria,
habría que preocuparse por el tamaño del bloque en el dispositivo de
lectura para leer en bloques de ese tamaño o un poquito menos, por si
acaso.
Mi propuesta para subir nota en tu asignatura sería:
1) Función para averiguar tamaño de bloque, si falla, usar tamaño
estándar.
2) lseek del fichero origen (o ficheros origen, porque... ¿el port
de cp es completo? [*]) y creación de un mapeo de ese tamaño. El tipo
de escritura debería ser:
a) diferida si el origen está en el mismo dispositivo.
b) directa si el origen no está en el mismo dispositivo.
3) Leer a saco en bloques de TAMAÑO_BLOQUE, escribiendo directamente en
el mapeo.
4) Desmapeo.
[*] Si hay que implementar cp completo, lo flipas, porque solo con el
recursivo, el -p, -a, etc. todo cambia y el número de syscalls crece
exponencialmente (por decir una barbaridad :-DDD).
--
Agur
Pablo Garaizar Sagarminaga
garaizar en eside.deusto.es
Más información sobre la lista de distribución eside-ghost