Записать большие данные в файл кеширования - PullRequest
5 голосов
/ 28 марта 2012

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

Мой код (упрощенный):

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

Я думаю, что есть проблема, связанная с проблемой кеширования, на самом деле во время «производительности быстрой записи» также увеличивается использование ОЗУ, когда прекращается увеличение использования ОЗУ, происходит падение производительности.

Что я пробовал:

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

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

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

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

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

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

1 Ответ

0 голосов
/ 28 марта 2012

Это как-то пытается написать до того, как он закончил писать предыдущий кусок и попадал в беспорядок?(кажется маловероятным, но очень странно, что 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);
    }
  }
}

РЕДАКТИРОВАТЬ: я настроил ваш пример кода для включения цикла while, необходимого для того, чтобы он записал файлправильный размер.

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

...