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





Я нашел статью это, и кажется, что это сложная программа, потому что вам также нужно очищать другие кеши.
Почему сделай сам?
Если вам нужно только определить скорость диска и вы не очень заинтересованы в том, чтобы узнать, как очистить буферы ввода-вывода из .NET, вы можете просто использовать утилиту DiskSpd из http://research.microsoft.com/barc/Sequential_IO/. Он имеет случайный / последовательный режимы с промывкой буфера и без нее.
На странице также есть несколько отчетов об исследованиях, связанных с вводом-выводом, которые могут оказаться полезными.
Константин: Спасибо! По этой ссылке есть EXE из командной строки, который выполняет то тестирование, которое я искал.
Я также нашел ссылку на этой странице на более интересную статью (в Word и PDF) на этой странице: Шаблоны последовательного программирования файлов и производительность с .NET
В этой статье рассказывается о производительности файлов без буферизации (iow, без кэширования чтения / записи - только чистая производительность диска).
Цитата прямо из статьи:
There is no simple way to disable FileStream buffering in the V2 .NET framework. One must invoke the Windows file system directly to obtain an un-buffered file handle and then ‘wrap’ the result in a FileStream as follows in 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);
Calling CreateFile() with the FILE_FLAG_NO_BUFFERING flag tells the file system to bypass all software memory caching for the file. The ‘true’ value passed as the third argument to the FileStream constructor indicates that the stream should take ownership of the file handle, meaning that the file handle will automatically be closed when the stream is closed. After this hocus-pocus, the un-buffered file stream is read and written in the same way as any other.
@Oliver: Я не смотрел этот код в (смотрит на часы) более 7 лет, так что, вероятно, все изменилось. Я почти уверен, что 7 лет назад он работал с C# /. NET 2.0 в VS2005 (или, может быть, VS2008, не уверен, что я уже переключился на тот момент.) Я посмотрю, смогу ли я найти исходный код, который я использовал тогда и отправьте ответ, если найду.
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);
Использование бинарного кода and эффективно убивает все параметры, но, с другой стороны, это маловероятная опечатка, поэтому мне интересно, в чем причина его использования.
Отклик Fix был почти правильным и лучше, чем PInvoke. Но в нем есть ошибки и не работает ...
Чтобы открыть файл без кеширования, необходимо сделать следующее:
const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000;
FileStream file = new FileStream(fileName, fileMode, fileAccess, fileShare, blockSize,
FileFlagNoBuffering | FileOptions.WriteThrough | fileOptions);
Несколько правил:
И не забывайте - есть также HDD Cache (который медленнее и меньше, чем кеш ОС), который вы не можете отключить этим (но иногда FileOptions.WriteThrough помогает не кэшировать записи). С этими параметрами у вас нет причин для сброса, но убедитесь, что вы правильно проверили, что этот подход не замедлит работу в случае, если ваша реализация кеша будет медленнее.
Я проголосовал за это, но это не сработало после тестирования - к сожалению, к тому моменту было уже слишком поздно отозвать мой голос! Код не компилируется (не может пройти
FileAccess.Readи аналогичныйCreateFile(), и если вы введете приведение перечислений, код не будет запущен - не может передатьnullв качестве hTemplate.