Каковы преимущества файлов с отображением памяти?

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

В частности, меня беспокоит следующее в порядке важности:

  • concurrency
  • произвольный доступ
  • производительности
  • простота использования
  • портативность

Ответ 1

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

Если ваше приложение может использовать данные "на месте" в файле с отображением памяти, он может входить без копирования; если вы используете системный вызов (например, Linux pread()), то обычно это связано с тем, что ядро ​​копирует данные из своих собственных буферов в пространство пользователя. Это дополнительное копирование требует не только времени, но и снижает эффективность кэшей ЦП путем доступа к этой дополнительной копии данных.

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

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


Очевидным недостатком файлов с отображением памяти является 32-разрядная ОС - вы можете легко исчерпать адресное пространство.

Ответ 2

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

Во время выполнения файл сопоставляется с памятью, преобразуется в массив C -style struct, и мы выполняем двоичный поиск, чтобы найти соответствующие номера деталей в качестве типов пользователей. Лишь несколько страниц памяти файла на самом деле читаются с диска - в зависимости от того, какие страницы попадают во время двоичного поиска.

  • Concurrency - У меня была проблема с реализацией, когда иногда память отображала файл несколько раз в одном пространстве процесса. Это была проблема, о которой я помню, потому что иногда система не могла найти достаточно большой свободный блок виртуальной памяти для сопоставления файла. Решение состояло в том, чтобы только один раз отобразить файл и разблокировать все вызовы. В ретроспективе использование полномасштабной службы Windows было бы круто.
  • Случайный доступ - двоичный поиск - это, безусловно, произвольный доступ и молния
  • Производительность - поиск выполняется очень быстро. Когда пользователи вводят всплывающее окно, отображается список соответствующих номеров продуктов, список сжимается по мере их ввода. При вводе нет заметного запаздывания.

Ответ 3

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

Вместо того, чтобы просматривать, писать и читать в файле, вы отображаете его в память и просто получаете доступ к битам, где вы ожидаете их.

Это может быть очень удобно, и в зависимости от интерфейса виртуальной памяти может повысить производительность. Повышение производительности может произойти из-за того, что теперь операционная система управляет этим предыдущим "файловым вводом-выводом" вместе со всем вашим программным доступом к памяти и может (теоретически) использовать алгоритмы подкачки и т.д., Которые она уже использует для поддержки виртуальную память для остальной части вашей программы. Однако это зависит от качества вашей базовой системы виртуальной памяти. Анекдоты, которые я слышал, говорят, что системы виртуальной памяти Solaris и * BSD могут демонстрировать лучшие улучшения производительности, чем система VM Linux, но у меня нет эмпирических данных, чтобы поддержать это. YMMV.

Concurrency появляется на картинке, когда вы рассматриваете возможность нескольких процессов с использованием одного и того же "файла" через сопоставленную память. В модели чтения/записи, если два процесса написаны в одну и ту же область файла, вы можете быть уверены, что одна из данных процесса поступит в файл, перезаписав данные другого процесса. Вы получите тот или другой, но не какой-то странный переплет. Я должен признать, что я не уверен, является ли это поведение обязательным по любому стандарту, но на это вы можете положиться. (Это действительно хороший вопрос о последующих действиях!)

В сопоставленном мире, напротив, представьте два процесса как "написание". Они делают это, делая "хранилища памяти", что приводит к тому, что O/S подкачки данных выходят на диск - в конце концов. Но в то же время можно ожидать перекрывающиеся записи.

Вот пример. Скажем, у меня есть два процесса, которые записывают 8 байтов со смещением 1024. Процесс 1 пишет "11111111", а процесс 2 записывает "22222222". Если они используют файловый ввод-вывод, то вы можете себе представить, что в глубине O/S есть буфер, полный 1s, и буфер, полный 2s, оба направляются в одно и то же место на диске. Один из них отправится туда первым, а второй - второй. В этом случае выигрывает второй. Однако, если я использую файловый подход с отображением памяти, процесс 1 будет идти в хранилище памяти 4 байта, за которым следует еще одно хранилище памяти 4 байта (допустим, что это максимальная память магазин размер). Процесс 2 будет делать то же самое. Основываясь на том, когда процессы выполняются, вы можете увидеть любое из следующего:

11111111
22222222
11112222
22221111

Решение этого - использовать явное взаимное исключение - это, вероятно, хорошая идея в любом случае. Во всяком случае, вы полагались на O/S, чтобы делать "правильную вещь" в случае ввода-вывода файлов чтения/записи.

Классификатор взаимного исключения - это мьютекс. Для файлов с отображением памяти я предлагаю вам взглянуть на мьютекс с отображением памяти, доступный с использованием (например,) pthread_mutex_init().

Изменить с помощью одной: если вы используете сопоставленные файлы, возникает соблазн вставить указатели на данные в файле, в самом файле (подумайте о связанном списке, хранящемся в сопоставленном файле). Вы не хотите этого делать, поскольку файл может отображаться на разных абсолютных адресах в разное время или в разных процессах. Вместо этого используйте смещения в отображаемом файле.

Ответ 4

Concurrency будет проблемой. Случайный доступ проще Производительность хороша. Простота использования. Не так хорошо. Портативность - не так жарко.

Я использовал их в системе Солнца давным-давно, и это мои мысли.