简体   繁体   中英

Write large data to file caching issue

I have a problem when I write a large amount of data <2GB to a file. First ~1.4GB data are written fast (100 MB/s) than the code become really slow (0-2 MB/s).

My code (simplified) is:

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

I think there is an issue related to caching problem, in fact during "fast write performance" RAM used increase as well, when RAM usage stop to increase there is a drop in performance.

What I have tried:

  • change to async write ->no significantly change

  • change array buffer size ->no significantly change

  • change fileBufferSize ->no significantly change, but with a large buffer ~100MB, write performance is fast and when RAM usage stop to increase, write performance goes to 0 and than, after a while, goes back to 100MB, it seams that cache buffer is "flushed"

  • change fileOption to WriteThrough ->performance are always slow..

  • adding after xx loops fs.Flush(true) ->no significantly change

  • uncomment Thread.Sleep(10) ->write speed is always good.....this is strange

Is it somehow trying to write before it's finished writing the previous chunk and getting in a mess? (seems unlikely, but it's very odd that the Thread.Sleep should speed it up and this might explain it). What happens if you modify the code inside the using statement to lock the filestream, like this?

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: I have tweaked your example code to include the while loop required to make it write a file of the correct size.

Incidentally, when I run the sample code it is very quick with or without the lock statement and adding the sleep slows it down significantly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM