Как отключить кэш диска в C # вызвать Win32 API CreateFile с FILE_FLAG_NO_BUFFERING - PullRequest
2 голосов
/ 01 января 2012

каждый, у меня много файлов, записываемых на диск в секунду, я хочу отключить дисковый кеш для повышения производительности, я ищу поиск в Google: win32 метод CreateFile с FILE_FLAG_NO_BUFFERING и Как очистить / очистить Windows READ кеш диска в C #? .

Я пишу небольшой код для проверки работоспособности:

const int FILE_FLAG_NO_BUFFERING = unchecked((int)0x20000000);

[DllImport("KERNEL32", SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
static extern SafeFileHandle CreateFile(
      String fileName,
      int desiredAccess,
      System.IO.FileShare shareMode,
      IntPtr              securityAttrs,
      System.IO.FileMode  creationDisposition,
      int                 flagsAndAttributes,
      IntPtr              templateFile);

static void Main(string[] args)
{
    var handler = CreateFile(@"d:\temp.bin", (int)FileAccess.Write, FileShare.None,IntPtr.Zero, FileMode.Create, FILE_FLAG_NO_BUFFERING, IntPtr.Zero);
    var stream = new FileStream(handler, FileAccess.Write, BlockSize);//BlockSize=4096
    byte[] array = Encoding.UTF8.GetBytes("hello,world");
    stream.Write(array, 0, array.Length);
    stream.Close();
}

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

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

var stream = new FileStream(handler, FileAccess.Write, 4096);
byte[] ioBuffer = new byte[4096];
byte[] array = Encoding.UTF8.GetBytes("hello,world");
Array.Copy(array, ioBuffer, array.Length);
stream.Write(ioBuffer, 0, ioBuffer.Length);
stream.Close();

он работает нормально, но я просто хочу, чтобы байты "привет, мир" не все. Я пытаюсь изменить размер блока на 1 или другое целое число (не кратное 512), получаю ту же ошибку. можете мне помочь?

Ответы [ 2 ]

4 голосов
/ 01 января 2012

Функция CreateFile () в режиме без буферизации налагает строгие требования на то, что можно, а что нельзя.Наличие буфера определенного размера (кратного размеру сектора устройства) является одним из них.

Теперь вы можете улучшить запись файлов таким образом, только если вы используете буферизацию в своем коде.Если вы хотите записать 10 байтов без буферизации, то режим без буферизации вам не поможет.

1 голос
/ 29 января 2014

Если я правильно понял ваши требования, я бы попробовал сначала:

Создать очередь с объектами, в которых есть данные в памяти и целевой файл на диске. Вы начинаете записывать файлы сначала просто в память, а затем в другом потоке начинаете проходить очередь, открывая дескрипторы файлового потока на основе порта завершения io (isAsync = True) - просто не открывайте их слишком много, как в какой-то момент, когда вы ' Вероятно, вы начнете терять производительность из-за перебора кэша и т. д. Вам необходимо выполнить профилирование, чтобы увидеть, какое оптимальное количество для вашей системы и ssd.

После каждого открытия вы можете использовать асинхронные методы файлового потока Begin ..., чтобы начать запись данных из памяти в файлы. isAsync предъявляет некоторые требования, так что это может быть не так просто, чтобы работать в каждом конкретном случае, как при обычном использовании файлового потока.

Будут ли какие-либо улучшения в использовании другого потока для создания файлов и другого потока для записи в них с использованием async api, это может быть только в том случае, если существует вероятность, что создание / открытие файлов заблокирует. SSD выполняет различные внутренние функции, чтобы обеспечить быстрый доступ к данным, поэтому, когда вы начнете заниматься такими видами высокопроизводительной работы, между контроллерами SSD могут возникнуть явные различия. Также возможно, что если драйверы контроллера не реализованы должным образом, ОС / Windows могут начать ощущать вялость или зависание. Сайты тестов аппаратного обеспечения на самом деле не акцентируют внимание на этом конкретном сценарии (например, создают и записывают x КБ в миллион файлов как можно скорее), и, несомненно, есть некоторые драйверы, которые работают медленнее, чем другие.

...