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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
0
13 881
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

Ответ принят как подходящий

Почему сделай сам?

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

Я проголосовал за это, но это не сработало после тестирования - к сожалению, к тому моменту было уже слишком поздно отозвать мой голос! Код не компилируется (не может пройти FileAccess.Read и аналогичный CreateFile(), и если вы введете приведение перечислений, код не будет запущен - не может передать null в качестве hTemplate.

Oliver 15.01.2016 17:28

@Oliver: Я не смотрел этот код в (смотрит на часы) более 7 лет, так что, вероятно, все изменилось. Я почти уверен, что 7 лет назад он работал с C# /. NET 2.0 в VS2005 (или, может быть, VS2008, не уверен, что я уже переключился на тот момент.) Я посмотрю, смогу ли я найти исходный код, который я использовал тогда и отправьте ответ, если найду.

Pretzel 16.01.2016 18:26

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 эффективно убивает все параметры, но, с другой стороны, это маловероятная опечатка, поэтому мне интересно, в чем причина его использования.

astrowalker 05.10.2020 15:22

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

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