2012-03-28 15 views
5

Tengo un problema cuando escribo una gran cantidad de datos < 2GB en un archivo. Los primeros datos ~ 1.4GB se escriben rápidamente (100 MB/s) que el código se vuelve realmente lento (0-2 MB/s).Escribir datos grandes en el problema de almacenamiento en caché de archivos

Mi código (simplificado) es:

//FileOptions FILE_FLAG_NO_BUFFERING = (FileOptions)0x20000000; 
    FileOptions fileOptions = FileOptions.SequentialScan; 

    int fileBufferSize = 1024 * 1024; 
    byte[] Buffer = new byte[32768]; 

    Random random = new Random(); 
    long fileSize = 2588490188; 
    long totalByteWritten = 0; 

    using (FileStream fs = File.Create(@"c:\test\test.bin", fileBufferSize, fileOptions)) 
    { 
     while (totalByteWritten < fileSize) 
     { 
      random.NextBytes(Buffer); 
      fs.Write(Buffer, 0, Buffer.Length); 
      totalByteWritten += Buffer.Length; 
      //Thread.Sleep(10); 
     } 
    } 

Creo que hay un problema relacionado con un problema de almacenamiento en caché, de hecho, durante el "rendimiento de escritura rápida" memoria RAM utilizada aumento, así, cuando parada de uso de memoria RAM para aumentar allí es una caída en el rendimiento.

Lo que he intentado:

  • cambio asíncrono escritura -> ningún cambio significativamente

  • cambio de gama de tamaño de búfer -> cambiar ninguna significativamente

  • cambio fileBufferSize - > No hay cambios significativos, pero con un gran búfer ~ 100MB, el rendimiento de escritura es rápido y cuando el uso de RAM se detiene para aumentar, escriba p endimiento va a 0 y que, después de un tiempo, se remonta a 100 MB, que las costuras que búfer de caché es "enrojecimiento"

  • cambio fileOption a WriteThrough -> rendimiento son siempre lento ..

  • añadiendo después xx bucles fs.Flush(true) -> cambiar significativamente sin

  • uncomment Thread.Sleep(10) -> velocidad de escritura es siempre bueno ..... esto es extraño

+0

Parece que thread.sleep está ayudando a borrar la memoria y volcarla al disco. ¿Puedes hacer un punto de referencia de la velocidad de escritura de tu HD? Creo que al principio todo está escrito en la memoria, hasta que está lleno y luego se escribe el archivo de paginación de Windows (ya que se maximizó la memoria) y el archivo continúa escribiendo, por lo que el rendimiento es bajo. pero podría estar equivocado :) – Dementic

+0

¿Hay alguna posibilidad de que haya algún software antivirus ejecutándose en el sistema que ralentiza el rendimiento después de que se llena la memoria RAM y los datos comienzan a escribirse en el disco? –

+0

Hm, a mi entender, 'FileOptions.SequentialScan' no tiene ningún uso en su escenario. Esto sería importante cuando * lectura * del disco no se escribe. Por lo que he entendido, esto es solo un fragmento de código simplificado, así que supongo que el 'aleatorizado.NextBytes' es solo un marcador de posición para tus datos reales. ¿De dónde provienen los datos reales? ¿Podría ser la recopilación de los datos reales la culpable? –

Respuesta

0

¿De alguna manera está tratando de escribir antes de que termine de escribir el fragmento anterior y meterse en un desastre? (Parece improbable, pero es muy extraño que el Thread.Sleep lo acelere y esto podría explicarlo). ¿Qué sucede si modifica el código dentro de la instrucción de uso para bloquear el filestream, así?

using (FileStream fs = File.Create(@"c:\testing\test.bin", fileBufferSize, fileOptions)) 
{ 
    while (fs.Position < fileBufferSize) 
    { 
    lock(fs) // this is the bit I have added to try to speed it up 
    { 
     random.NextBytes(Buffer); 
     fs.Write(Buffer, 0, Buffer.Length); 
    } 
    } 
} 

EDIT: He ajustado el código de ejemplo para incluir el bucle while se requiere para que sea escribir un archivo del tamaño correcto.

Por cierto, cuando ejecuto el código de ejemplo, es muy rápido con o sin la instrucción lock y al agregar el modo de suspensión lo desacelera significativamente.

Cuestiones relacionadas