Меня интересует перспектива использования ввода-вывода с отображением памяти, предпочтительно с использованием возможностей boost :: interprocess для кросс-платформенной поддержки, чтобы отображать несмежные блоки системного размера страницы в файле в непрерывное адресное пространство в памяти.
Упрощенный конкретный сценарий:
У меня есть несколько структур «простых старых данных», каждая из которых имеет фиксированную длину (меньше размера системной страницы). Эти структуры объединены в (очень длинный) поток с типом и расположением структур, определяемых значения тех структур, которые продолжают их в потоке. Я стремлюсь минимизировать задержку и максимизировать пропускную способность в требовательной параллельной среде.
Я могу очень эффективно читать эти данные, отображая их в памяти блоками, по крайней мере, в два раза превышающими размер системной страницы ... и устанавливая новое отображение сразу же после прочтения структуры, выходящей за пределы предпоследней границы системной страницы. Это позволяет коду, который взаимодействует с простыми-старыми структурами данных, блаженно не осознавать, что эти структуры отображены в память ... и, например, мог напрямую сравнивать две разные структуры с помощью memcmp (), не заботясь о границах страницы.
Что интересно, так это в отношении обновления этих потоков данных ... пока они (одновременно) читаются. Стратегия, которую я хотел бы использовать, основана на «копировании при записи» с детализацией на уровне системной страницы ... по сути, написание «оверлейных страниц», позволяющих одному процессу читать старые данные, а другой - обновленные данные.
Управление тем, какие оверлейные страницы и когда использовать, не обязательно тривиально ... это не моя главная забота. Моя основная проблема заключается в том, что у меня может быть структура, охватывающая страницы 4 и 5, а затем обновить структуру, полностью содержащуюся на странице 5 ... записать новую страницу в местоположение 6 ... оставить страницу 5 для `` сборщика мусора '', когда она определено, что он больше недоступен. Это означает, что, если я отображаю страницу 4 в ячейку M, мне нужно отобразить страницу 6 в ячейку памяти M + page_size ..., чтобы иметь возможность надежно обрабатывать структуры, которые пересекают границы страницы, используя существующие (не связанные с отображением памяти- осведомленные) функции.
Я пытаюсь разработать лучшую стратегию, и мне мешает документация, которую я считаю неполной. По сути, мне нужно отделить выделение адресного пространства от отображения памяти в это адресное пространство. С mmap () я знаю, что могу использовать MAP_FIXED - если я хочу явно контролировать местоположение сопоставления ... но я не понимаю, как мне следует зарезервировать адресное пространство, чтобы сделать это безопасно. Могу ли я сопоставить / dev / zero для двух страниц без MAP_FIXED, а затем дважды использовать MAP_FIXED для сопоставления двух страниц в это выделенное пространство с явными адресами виртуальной машины? Если да, следует ли мне также трижды вызывать munmap ()? Будет ли это утечка ресурсов и / или какие-либо другие нежелательные накладные расходы? Чтобы сделать проблему еще более сложной, мне хотелось бы сопоставимого поведения в Windows ... есть ли способ сделать это? Существуют ли изящные решения, если я поставлю под угрозу свои кроссплатформенные амбиции?
--
Спасибо за ответ, Махмуд ... Я прочитал и думаю, что понял этот код ... Я скомпилировал его под Linux, и он ведет себя так, как вы предлагаете.
Меня больше всего беспокоит строка 62 - использование MAP_FIXED. Он делает некоторые предположения о mmap, которые мне не удалось подтвердить, когда я прочитал документацию, которую смог найти. Вы сопоставляете страницу «обновления» с тем же адресным пространством, что и mmap (), возвращаемым изначально - я предполагаю, что это «правильно», то есть не то, что просто случайно работает в Linux? Я также должен предположить, что он работает кросс-платформенным для сопоставлений файлов, а также для анонимных сопоставлений.
Образец определенно продвигает меня вперед ... документируя, что то, что мне в конечном итоге нужно, вероятно, достижимо с помощью mmap () в Linux - по крайней мере. Что мне действительно нужно, так это указатель на документацию, которая показывает, что строка MAP_FIXED будет работать, как демонстрирует образец ... и, в идеале, преобразование от специфичного для Linux / Unix mmap () к независимому от платформы (Boost :: interprocess ) подход.