2009-09-20 9 views
56

Me enteré de que, de forma predeterminada, las E/S en los programas están almacenadas temporalmente, es decir, se sirven desde un almacenamiento temporal al programa solicitante. Entiendo que el almacenamiento en búfer mejora el rendimiento de E/S (quizás reduciendo las llamadas al sistema). He visto ejemplos de deshabilitar el almacenamiento en búfer, como setvbuf en C. ¿Cuál es la diferencia entre los dos modos y cuándo se debe usar uno sobre el otro?Buffered versus unbuffered IO

Respuesta

90

Desea la salida sin búfer siempre que desee asegurarse de que la salida se haya escrito antes de continuar. Un ejemplo es el error estándar en una biblioteca de tiempo de ejecución de C; por lo general, esto no está almacenado de forma predeterminada. Dado que los errores son (afortunadamente) poco frecuentes, usted quiere saber sobre ellos de inmediato. Por otro lado, la salida estándar es almacenada en memoria intermedia simplemente porque se supone que habrá muchos más datos que la atraviesen.

Otro ejemplo es una biblioteca de registro. Si sus mensajes de registro se mantienen dentro de los almacenamientos intermedios en su proceso y su proceso se volca, es muy probable que la salida nunca se escriba.

Además, no solo se minimizan las llamadas al sistema, sino también las E/S de disco. Digamos que un programa lee un archivo de un byte a la vez. Con la entrada sin búfer, saldrá al disco (relativamente muy lento) para cada byte, aunque probablemente tenga que leer en un bloque completo de todos modos (el hardware del disco en sí mismo puede tener almacenamientos intermedios pero todavía está saliendo al controlador del disco) que va a ser más lento que el acceso en memoria).

Mediante el almacenamiento en búfer, se lee todo el bloque en el búfer de una vez y luego se le envían los bytes individuales desde el área del búfer (en memoria, increíblemente rápida).

Tenga en cuenta que el almacenamiento en búfer puede tomar muchas formas, tales como en el siguiente ejemplo:

+-------------------+-------------------+ 
| Process A   | Process B   | 
+-------------------+-------------------+ 
| C runtime library | C runtime library | C RTL buffers 
+-------------------+-------------------+ 
|    OS caches    | Operating system buffers 
+---------------------------------------+ 
|  Disk controller hardware cache | Disk hardware buffers 
+---------------------------------------+ 
|     Disk    | 
+---------------------------------------+ 
21

desea una salida sin búfer cuando ya tiene gran secuencia de bytes listos para escribir en el disco, y quieren evite una copia extra en un segundo buffer en el medio.

Las secuencias de salida almacenadas en búfer acumularán los resultados de escritura en un búfer intermedio, enviándolo al sistema de archivos del SO solo cuando se hayan acumulado suficientes datos (o se solicite flush()). Esto reduce la cantidad de llamadas al sistema de archivos. Dado que las llamadas al sistema de archivos pueden ser costosas en la mayoría de las plataformas (en comparación con memcpy corto), la salida en búfer es una ganancia neta cuando se realiza una gran cantidad de pequeñas escrituras. La salida sin búfer generalmente es mejor cuando ya tiene búferes grandes para enviar; copiar en un búfer intermedio no reducirá el número de llamadas al sistema operativo e introduce trabajo adicional.

La salida sin búfer tiene nada que ver con para asegurar que sus datos lleguen al disco; esa funcionalidad es provista por flush(), y funciona en streams almacenados y no almacenados. Las grabaciones IO sin búfer no garantizan que los datos hayan llegado al disco físico: el sistema de archivos del sistema operativo puede retener indefinidamente una copia de sus datos, nunca escribirlos en el disco, si así lo desea. Solo es necesario enviarlo al disco cuando invocas flush(). (Tenga en cuenta que close() llamará a flush() en su nombre).

+0

¿Llamar a 'flush()' garantiza que está escrito en el disco? Pensé que solo se lo pasaba al búfer del disco. – jrdioko

+2

Necesita 'O_SYNC' para garantizar las escrituras. – moshbear