IO из сопоставленного файла против IO с использованием файловых потоков

Я работаю над приложением, которое должно работать с большими объемами данных (в ГБ). Мне не нужны все данные сразу в любой момент времени. Можно разделить данные и работать только с разделом (и, следовательно, вносить его в память) в любом конкретном случае.

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

Вот запросы, которые у меня есть:

  1. Насколько отличается использование файлов с отображенной памятью (я планирую использовать boost :: file_mapping и работаю над окнами) для файлового ввода-вывода по сравнению с использованием файловых потоков?
  2. Насколько быстрее можно ожидать чтения / записи данных в случае файлов с отображенной памятью по сравнению с использованием файловых потоков (на традиционном жестком диске 7200 об / мин)?
  3. Являются ли файлы с отображением в памяти единственным способом справиться с такими огромными объемами данных? Есть ли лучшие способы сделать это (учитывая мой вариант использования)?

4

Решение

(Отказ от ответственности: я автор предложил Boost.AFIO)

Насколько отличается использование файлов с отображенной памятью (я планирую использовать
boost :: file_mapping, и я работаю над окнами) для файла ввода-вывода, чем
используя файловые потоки?

Грубо упрощенный ответ:

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

Более точный ответ:

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

Насколько быстрее можно ожидать чтения / записи данных
быть в случае отображенных в память файлов по сравнению с использованием файла
потоки (на традиционном жестком диске 7200 об / мин)?

Вероятно, не заметно. Если вы сравниваете разницу, это, вероятно, мешающие факторы, такие как различные алгоритмы кэширования. Жесткий диск настолько медленный, что всегда будет доминирующим фактором.

Теперь, если вы действительно спрашиваете, как эффективное эти два сравниваются с точки загрузки системы, тогда файлы с отображением в памяти, вероятно, будут гораздо более эффективными. STL iostreams копирует память, по крайней мере, один раз, плюс на самом «немедленном» вводе-выводе в Windows это действительно memcpy из небольшой карты внутренней памяти, настроенной ядром Windows для вашего процесса, так что это минимум две копии памяти для всего, что вы читаете.

Самый эффективный из всех — это всегда O_DIRECT / FILE_FLAG_NO_BUFFERING со всеми поставленными ошибками, но очень редко вы пишете алгоритм кэширования гораздо лучше, чем операционная система. В конце концов, они потратили десятилетия, настраивая свои алгоритмы.

Являются ли файлы отображены в памяти
единственный способ справиться с такими огромными объемами данных? Там лучше
способы сделать это (учитывая мой вариант использования)?

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

3

Другие решения

  • содержимое файла никогда не попадет в файл подкачки
  • после сопоставления файла системный вызов не требуется
  • система оптимизирует использование оперативной памяти
  • в случае записи в файл с отображенной памятью и сбой вашего процесса содержимое файла будет соответствовать содержимому памяти без необходимости выполнения окончательного (записи / очистки) системного вызова
  • несколько процессов (на одном компьютере) могут видеть содержимое одного и того же файла и сразу же вносить изменения (читатель / писатель). И содержимое файла не попадет в файл подкачки для каждого читателя / писателя.
  • несколько процессов будут использовать одну и ту же оперативную память для сопоставлений одного и того же файла
2

Насколько отличается использование файлов с отображенной памятью (я планирую использовать boost :: file_mapping и работаю над окнами) для файлового ввода-вывода по сравнению с использованием файловых потоков?

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

Это предъявляет требования к вашему приложению и хранилищу данных. Вы должны убедиться, что вы можете получить доступ к своим данным таким образом. Вы также должны убедиться, что вы можете разместить данные в адресуемой памяти — с 32-битной системой вы будете ограничены несколькими гигабайтами данных.

Насколько быстрее можно ожидать чтения / записи данных в случае файлов с отображенной памятью по сравнению с использованием файловых потоков (на традиционном жестком диске 7200 об / мин)?

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

Являются ли файлы с отображением в памяти единственным способом справиться с такими огромными объемами данных? Есть ли лучшие способы сделать это (учитывая мой вариант использования)?

Это зависит от того, каково ваше реальное дело.

1

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

Как я уже сказал, разница между скоростью вашей памяти и скоростью жесткого диска в принципе.

У меня нет большого опыта работы с большими данными, поэтому я не чувствую, что могу ответить на этот вопрос.

-1
По вопросам рекламы [email protected]