[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