2010-09-20 8 views
14

Estoy trabajando en una aplicación que escribe secuencialmente un archivo grande (y no lo lee en absoluto), y me gustaría usar posix_fadvise() para optimizar el comportamiento del sistema de archivos.¿Qué posix_fadvise() args para la escritura secuencial de archivos?

La descripción de la función en la página de manual sugiere que la estrategia más adecuada sería POSIX_FADV_SEQUENTIAL. Sin embargo, la descripción de la implementación de Linux duda de que:

En Linux, POSIX_FADV_NORMAL establece la ventana readahead al tamaño predeterminado para el dispositivo de respaldo; POSIX_FADV_SEQUENTIAL duplica este tamaño, y POSIX_FADV_RANDOM desactiva por completo la lectura de archivos.

Como solo estoy escribiendo datos (sobreescribiendo también los archivos posiblemente), no espero ninguna readahead. ¿Debo seguir con mi POSIX_FADV_SEQUENTIAL o más bien usar POSIX_FADV_RANDOM para desactivarlo?

¿Qué hay de otras opciones, como POSIX_FADV_NOREUSE? ¿O tal vez no use posix_fadvise() para escribir?

Respuesta

5

Todo depende de la localidad temporal de sus datos. Si su aplicación no necesita los datos poco después de su escritura, puede ir con POSIX_FADV_NOREUSE para evitar escribir en la memoria caché del búfer (de forma similar a la O_DIRECT del open()).

+8

Tenga en cuenta que POSIX_FADV_NOREUSE no está implementado en el kernel de Linux. – smoors

0

En cuanto a las escrituras, creo que puede confiar en que el programador IO de disco de IO hará lo correcto.

Debe tener en cuenta que, si bien posix_fadvise está específicamente diseñado para brindarle al kernel sugerencias sobre futuros patrones de uso de archivos, el kernel también tiene otros datos para ayudarlo.

Si no abre el archivo para leer, entonces solo necesitaría leer los bloques cuando se escribieron parcialmente. Si tuviera que truncar el archivo a 0, entonces ni siquiera tiene que hacer eso (dijo que estaba sobrescribiendo).

32

La mayoría de los indicadores posix_fadvise() (por ejemplo, POSIX_FADV_SEQUENTIAL y POSIX_FADV_RANDOM) son sugerencias sobre readahead en lugar de escritura.

Hay algunos consejos de Linus here y here sobre cómo obtener un buen rendimiento de escritura secuencial. La idea es romper el archivo en gran ish (8MB) ventanas, a continuación, haciendo lazo alrededor:

  • escriben por su ventana con N write();
  • solicitud asincrónica escritura fuera de la ventana N con sync_file_range(..., SYNC_FILE_RANGE_WRITE)
  • Espere a que la escritura fuera de la ventana N-1 para completar con sync_file_range(..., SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER)
  • ventana gota N-1 de la memoria intermedia de páginas con posix_fadvise(..., POSIX_FADV_DONTNEED)

De esta forma, nunca tendrá más de dos ventanas que valgan la pena en la memoria caché de la página, pero aún así obtiene que el kernel escriba parte de la memoria caché en el disco mientras completa la siguiente parte.

+1

Fantástico, esto es lo que necesitaba para hacer utee (https: // github.com/aktau/utee) no arruinar el caché sino mantenerse rápido. ¡Gracias! – Aktau

Cuestiones relacionadas