Подтвердить что ты не робот

Производительность сопоставленных файлов памяти Win32 по сравнению с CRT fopen/fread

Мне нужно читать (сканировать) файл последовательно и обрабатывать его содержимое. Размер файла может быть от очень маленького (несколько КБ) до очень большого (несколько ГБ).

Я попробовал два метода с использованием VC10/VS2010 на 64-разрядной версии Windows 7:

  • Отображаемые файлы памяти Win32 (т.е. CreateFile, CreateFileMapping, MapViewOfFile и т.д.).
  • fopen и fread из CRT.

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

Для MMF используются следующие операторы С++:

HANDLE hFile = CreateFile(
    filename,
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_SEQUENTIAL_SCAN,
    NULL
    );

HANDLE hFileMapping = CreateFileMapping(
    hFile,
    NULL,
    PAGE_READONLY,
    0,
    0,
    NULL
    );

Файл читается последовательно, фрагмент куском; каждый кусок SYSTEM_INFO.dwAllocationGranularity по размеру.

Учитывая, что скорость почти одинакова с MMF и CRT, я бы использовал функции CRT, потому что они более простые и многоплатформенные. Но мне любопытно: правильно ли я использую технику MMF? Нормально ли, что производительность MMF в этом случае файла scannig последовательно совпадает с CRT?

Спасибо.

4b9b3361

Ответ 1

Я считаю, что вы не увидите большой разницы, если вы последовательно будете обращаться к файлу. Поскольку файловый ввод-вывод очень сильно кэширован, вероятно, также используется + read-ahead.

Все будет по-другому, если у вас было много "переходов" во время обработки файлов. Затем каждый раз, когда установка нового указателя файла и чтение новой части файла, вероятно, будет убивать CRT, тогда как MMF предоставит вам максимально возможную производительность

Ответ 2

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

Для больших файлов MMF может уменьшить локальность данных и даже привести к копированию всего или части файла, помещенного в файл подкачки, тогда как обработка через CRT с использованием небольшого буфера будет проходить в ОЗУ. В этом случае MMF, вероятно, будет медленнее. Вы можете смягчить это, только сопоставление в части основного файла за раз, но тогда все становится более сложным без какой-либо вероятной победы над прямым последовательным вводом-выводом.

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

Ответ 3

Я думал, что файл с отображением памяти техника может быть быстрее, чем CRT функции, но некоторые тесты показали, что скорость почти одинакова для обоих случаев.

Вероятно, вы попадаете в кеш файловой системы для своих тестов. Если вы явно не создадите дескрипторы файлов для обхода кеша файловой системы (FILE_FLAG_NO_BUFFERING при вызове CreateFile), кэш файловой системы начнет использовать и сохраняет файлы с недавно полученным доступом в памяти.

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

У Gustavo Duarte есть отличная статья о файлах с отображением памяти (с общей перспективы ОС).

Ответ 4

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

Или, если у вас есть алгоритм, который работает только с памятью, то файлы с mem-mapped могут быть более легкими.