Файлы с отображением памяти могут использоваться для замены доступа для чтения/записи или для поддержки совместного использования. Когда вы используете их для одного механизма, вы получаете и другой.
Вместо того, чтобы просматривать и писать и читать в файле, вы отображаете его в память и просто получаете доступ к битам, где вы ожидаете их.
Это может быть очень удобно и в зависимости от интерфейса виртуальной памяти может повысить производительность. Повышение производительности может произойти из-за того, что теперь операционная система управляет этим предыдущим «файловым вводом-выводом» вместе со всем вашим программным доступом к памяти и может (теоретически) использовать алгоритмы подкачки и т. Д., Которые она уже использует для поддержки виртуальная память для отдыха вашей программы. Однако это зависит от качества вашей базовой системы виртуальной памяти. Анекдоты, которые я слышал, говорят, что системы виртуальной памяти Solaris и * BSD могут демонстрировать лучшие улучшения производительности, чем система VM Linux, но у меня нет эмпирических данных, чтобы поддержать это. YMMV.
Параллелизм приходит в картину, когда вы рассматриваете возможность нескольких процессов с использованием одного и того же «файла» через сопоставленную память. В модели чтения/записи, если два процесса написаны в одну и ту же область файла, вы можете быть уверены, что одна из данных процесса поступит в файл, перезаписав данные другого процесса. Вы получите тот или другой, но не какой-то странный переплет. Я должен признать, что я не уверен, является ли это поведение обязательным по любому стандарту, но на это вы можете положиться. (На самом деле это вопрос о том, что нужно ответить!)
В сопоставленном мире, напротив, представьте себе два процесса, которые «пишут». Они делают это, делая «хранилища памяти», что приводит к тому, что 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().
Редактировать с помощью одного: если вы используете сопоставленные файлы, возникает соблазн вставить указатели на данные в файле в самом файле (подумайте о связанном списке, хранящемся в сопоставленном файле). Вы не хотите этого делать, поскольку файл может отображаться на разных абсолютных адресах в разное время или в разных процессах. Вместо этого используйте смещения в отображаемом файле.
Не будет ли бинарный поиск медленным, поскольку страницы будут прочитаны для каждой попытки? Или операционная система достаточно умна, чтобы эффективно справляться с этим? – jjxtra 2013-11-02 04:12:36
Я полагаю, что использование ввода-вывода с отображением памяти является бесполезным для двоичного поиска, так как поиск будет иметь доступ только к нескольким отдельным клавишам в относительно отдаленных местах памяти, но ОС будет загружать на 4 тыс. Страниц для каждого такого запроса. Но опять же, файл с частями не сильно меняется, поэтому кеш помогает покрыть это. Но, строго говоря, я считаю, что традиционный поиск/чтение будет лучше здесь. Наконец, 1 мил в наши дни не так много. Почему бы просто не хранить все это в ОЗУ? – 2013-11-11 14:50:47