Как очистить/очистить дисковый кеш Windows READ на C#?
Вопрос
Если я пытаюсь определить скорость чтения диска, я могу написать программу для записи файлов в файловую систему, а затем прочитать эти файлы обратно.К сожалению, это не дает точной скорости чтения, поскольку 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);
Несколько правил:
- BlockSize должен соответствовать размеру кластера жесткого диска (в большинстве случаев 4096).
- изменение позиции файла должно соответствовать размеру кластера
- вы не можете читать/записывать меньше, чем размер блока, или блок не выровнен по размеру
И не забывайте - есть также кэш жесткого диска (который медленнее и меньше, чем кеш ОС), который вы не можете отключить (но иногда 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);
я нашел этот статья и кажется, что это сложная программа, потому что вам придется очищать еще и другие кеши.