2012-03-28 17 views
5

Mam problem, gdy piszę dużą ilość danych < 2 GB do pliku. Pierwsze ~ 1,4GB dane są zapisywane szybko (100 MB/s), a kod staje się naprawdę wolny (0-2 MB/s).Zapisywanie dużych danych do pamięci podręcznej problemu

Mój kod (uproszczone) wynosi:

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

Myślę, że jest to problem związany z problemem buforowania, w rzeczywistości podczas „fast wydajność zapisu” RAM wykorzystywane wzrost, jak również, gdy przystanek wykorzystanie RAM tam zwiększyć to spadek wydajności.

Co próbowałem:

  • zmiana asynchroniczny zapis -> nie zmienia się znacząco

  • rozmiar bufora zmiana tablicy -> nie zmienia się znacząco

  • zmianę fileBufferSize - > nie zmienia się znacząco, ale przy dużym buforze ~ 100MB, wydajność zapisu jest szybka, a gdy użycie pamięci RAM przestaje rosnąć, napisz p erformance idzie do 0 i niż po pewnym czasie wraca do 100MB, szwy, że bufor cache to "przepłukać"

  • zmiana fileOption do WriteThrough -> wydajność zawsze są powolne ..

  • dodając po xx pętle fs.Flush(true) -> nie zmienia się znacząco

  • odkomentuj Thread.Sleep(10) -> prędkość zapisu jest zawsze dobre ..... to jest dziwne

+0

Wygląda na to, że thread.sleep pomaga odzyskać pamięć i zrzucić ją na dysk. możesz zrobić wzorzec szybkości zapisu w hd? myślę, że na początku wszystko jest zapisywane do pamięci, dopóki nie jest pełna, a następnie zapisywany jest zarówno plik stronicowania systemu Windows (od momentu maksymalnego zwiększenia pamięci), jak i plik kontynuuje pisanie, więc wydajność spada. ale może się mylę :) – Dementic

+0

Czy jest jakieś oprogramowanie antywirusowe działające w systemie, które spowalnia działanie po zapełnieniu pamięci RAM i zaczyna zapisywać dane na dysku? –

+0

Hm, w moim rozumieniu "FileOptions.SequentialScan" nie ma żadnego zastosowania w twoim scenariuszu. Jest to ważne, gdy * odczyt * z dysku nie jest zapisywany. Z tego co rozumiem, jest to tylko uproszczony fragment kodu, więc domyślam się, że'random.NextBytes 'jest tylko symbolem zastępczym dla prawdziwych danych. Skąd pochodzą prawdziwe dane? Czy sprawcą może być zbieranie prawdziwych danych? –

Odpowiedz

0

Czy w jakiś sposób próbuje się napisać, zanim skończy się pisanie poprzedniego fragmentu i stanie się bałaganem? (wydaje się mało prawdopodobne, ale to bardzo dziwne, że Thread.Sleep powinien go przyspieszyć, co może to wyjaśnić). Co się stanie, jeśli zmodyfikujesz kod wewnątrz instrukcji using, aby zablokować strumień plików, w ten sposób?

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

EDYCJA: Wprowadziłem poprawkę do przykładowego kodu, aby uwzględnić pętlę while wymaganą do zapisania pliku o prawidłowym rozmiarze.

Nawiasem mówiąc, po uruchomieniu kodu przykładowego jest bardzo szybki z lub bez oświadczenia lock i dodanie snu spowalnia znacznie.

Powiązane problemy