Как очистить / очистить кэш диска Windows READ в C #? - PullRequest
7 голосов
/ 23 сентября 2008

Если я пытаюсь определить скорость чтения диска, я могу написать код для записи файлов в файловую систему, а затем прочитать их обратно. К сожалению, это не дает точную скорость чтения, потому что Windows выполняет кэширование чтения с диска.

Можно ли очистить кэш чтения диска на диске в C # / .Net (или, возможно, с помощью вызовов Win32 API), чтобы я мог читать файлы непосредственно с диска без их кэширования?

Ответы [ 5 ]

13 голосов
/ 24 сентября 2008

Константин: Спасибо! Эта ссылка имеет EXE-файл командной строки, который выполняет тестирование, которое я искал.

Я также нашел ссылку с этой страницы на более интересную статью (в Word и PDF) на этой странице: Шаблоны последовательного программирования файлов и производительность с .NET

В этой статье речь пойдет о производительности небуферизованных файлов (а значит, нет кэширования при чтении / записи - только сырая производительность диска).

Цитируется прямо из статьи:

Нет простого способа отключить Буферизация FileStream в V2 .NET фреймворк. Нужно вызвать Windows файловая система напрямую, чтобы получить дескриптор небуферизованного файла, а затем «Обернуть» результат в FileStream как следует в C #:

    [DllImport("kernel32", SetLastError=true)]
    static extern unsafe SafeFileHandle CreateFile(
        string FileName,           // file name
        uint DesiredAccess,        // access mode
        uint ShareMode,            // share mode
        IntPtr SecurityAttributes, // Security Attr
        uint CreationDisposition,  // how to create
        uint FlagsAndAttributes,   // file attributes
        SafeFileHandle  hTemplate // template file  
        );

    SafeFileHandle handle = CreateFile(FileName,
                            FileAccess.Read,
                            FileShare.None,
                            IntPtr.Zero,
                            FileMode.Open,
                             FILE_FLAG_NO_BUFFERING,
                            null);

    FileStream stream = new FileStream(handle, 
                    FileAccess.Read, 
                    true, 
                    4096);

Вызов CreateFile () с Флаг FILE_FLAG_NO_BUFFERING сообщает файловая система для обхода всего программного обеспечения кеширование памяти для файла. «Истинное» значение передается как третье аргумент для конструктора FileStream указывает, что поток должен принимать владение дескриптором файла, то есть что дескриптор файла будет автоматически закрывается, когда Поток закрыт. После этого hocus-pocus, небуферизованный файл поток читается и записывается в том же как и любой другой.

11 голосов
/ 03 сентября 2009

Ответ Fix был почти правильным и лучше, чем PInvoke. Но у него есть ошибки и он не работает ...

Чтобы открыть файл без кэширования, нужно сделать следующее:

const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000;

FileStream file = new FileStream(fileName, fileMode, fileAccess, fileShare, blockSize,
    FileFlagNoBuffering | FileOptions.WriteThrough | fileOptions);

Несколько правил:

  1. blockSize должен соответствовать размеру кластера жесткого диска (4096 большую часть времени)
  2. Изменение положения файла должно соответствовать размеру кластера
  3. вы не можете читать / писать меньше, чем blockSize или блок не выровнен по размеру

И не забывайте - есть также HDD Cache (который медленнее и меньше, чем OS кэш), который вы не можете этим отключить (но иногда FileOptions.WriteThrough помогает не кэшировать записи). С этими опциями у вас нет причин сбрасывать, но убедитесь, что вы правильно протестировали, что этот подход не замедлит процесс, если ваша реализация кэша будет медленнее.

4 голосов
/ 23 сентября 2008

Почему DIY?

Если вам нужно только определить скорость диска и не интересуетесь, как очищать буферы ввода-вывода из .NET, вы можете просто использовать утилиту DiskSpd из http://research.microsoft.com/barc/Sequential_IO/.. В ней есть случайные / последовательные режимы с и без очистка буфера.

На этой странице также есть некоторые исследовательские отчеты, связанные с вводом / выводом, которые могут оказаться полезными.

3 голосов
/ 21 декабря 2008
const int FILE_FLAG_NO_BUFFERING = 0x20000000;
return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,64 * 1024,
(FileOptions)FILE_FLAG_NO_BUFFERING | FileOptions.Asynchronous
& FileOptions.SequentialScan);
0 голосов
/ 23 сентября 2008

Я нашел эту статью, и кажется, что это сложная программа, потому что вам также нужно очищать другие кэши.

...