Как очистить/очистить дисковый кеш Windows READ на C#?

StackOverflow https://stackoverflow.com/questions/122362

Вопрос

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

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

Это было полезно?

Решение

Почему своими руками?

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

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

Другие советы

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

Ответ 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. вы не можете читать/записывать меньше, чем размер блока, или блок не выровнен по размеру

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top