2012-03-28 3 views
5

У меня возникла проблема, когда я пишу большое количество данных < 2GB в файл. Первые ~ 1,4 ГБ данные записываются быстро (100 МБ/с), чем код становится очень медленным (0-2 МБ/с).Запись больших данных в проблему кэширования файлов

Мой код (упрощенно) является:

//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); 
     } 
    } 

Я думаю, что есть проблема, связанная с проблемой кэширования, на самом деле во время «высокая производительность записи» RAM используется увеличение, а также, при использовании оперативной памяти остановка для увеличения там это снижение производительности.

То, что я не пробовал:

  • изменение асинхронной записи -> нет существенных изменений

  • изменения массива размера буфера не -> нет существенных изменений

  • изменений fileBufferSize - > нет значительного изменения, но с большим буфером ~ 100 МБ производительность записи быстро и когда использование ОЗУ перестает увеличиваться, пишите p идет в наилучших показателей 0 и чем, через некоторое время, возвращается к 100MB, швы, что буфер кэш «покраснел»

  • изменение fileOption к WriteThrough -> производительность всегда медленно ..

  • добавив после хх петли fs.Flush(true) -> не существенно не изменится

  • раскомментируйте Thread.Sleep(10) -> скорость записи всегда хорошо ..... это странно

+0

Кажется, что thread.sleep помогает памяти очищаться и сбрасываться на диск. можете ли вы сделать тест скорости записи hd? я думаю, что при запуске все записывается в память до тех пор, пока оно не будет заполнено, а затем будет записываться файл подкачки Windows (поскольку вы максимизировали память), и ваш файл продолжает писать, поэтому производительность становится низкой. но я могу ошибаться :) – Dementic

+0

Есть вероятность, что в системе есть антивирусное программное обеспечение, которое замедляет производительность после заполнения ОЗУ, и данные начинают записываться на диск? –

+0

Хм, на мой взгляд, «FileOptions.SequentialScan» вообще не используется в вашем сценарии. Это было бы важно, когда * чтение * с диска не записывалось. Насколько я понял, это всего лишь упрощенный фрагмент кода, поэтому я думаю, что «random.NextBytes» - это всего лишь заполнитель для ваших реальных данных. Откуда берутся настоящие данные? Может ли сбор фактических данных быть виновником? –

ответ

0

Как-то пытаться написать, прежде чем он закончит писать предыдущий кусок и попасть в беспорядок? (кажется маловероятным, но очень странно, что Thread.Sleep должен ускорить его, и это может объяснить это). Что произойдет, если вы измените код внутри оператора using, чтобы заблокировать поток, как это?

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: Я подправил свой пример код, чтобы включить время цикла, необходимый, чтобы сделать это написать файл нужного размера.

Кстати, когда я запускаю образец кода, он очень быстр с оператором lock или без него, и добавление сна значительно замедляет его.

Смежные вопросы