stringtranslate.com

Файл, отображенный в памяти

Файл , отображенный в память, представляет собой сегмент виртуальной памяти [1] , которому назначена прямая корреляция байт-в-байт с некоторой частью файла или файлоподобного ресурса. Этот ресурс обычно представляет собой файл, который физически присутствует на диске, но также может быть устройством, объектом общей памяти или другим ресурсом, на который операционная система может ссылаться через файловый дескриптор . После появления эта корреляция между файлом и пространством памяти позволяет приложениям обрабатывать отображенную часть так, как если бы это была первичная память.

История

ТОПС-20 ПМАП

Ранней ( около  1969 г. ) [2] реализацией этого был системный вызов PMAP в операционной системе TOPS-20 DEC -20 , [3] функция, используемая системой баз данных System-1022 компании Software House . [4]

SunOS 4 mmap

SunOS 4 [5] представила Unix , которая mmapпозволяла программам «отображать файлы в памяти». [1]

Расширяемые файлы памяти Windows (GMMF)

Спустя два десятилетия после выпуска PMAP от TOPS-20, в Windows NT появились файлы с возможностью масштабирования и отображения в памяти (GMMF).

Поскольку « CreateFileMappingфункция требует передачи ей размера», а изменение размера файла не всегда легко осуществимо, был разработан API GMMF. [6] [7] Использование GMMF требует объявления максимального размера, до которого может вырасти размер файла, но неиспользуемое пространство не тратится впустую.

Преимущества

Преимущество отображения файла в память заключается в повышении производительности ввода-вывода, особенно при использовании с большими файлами. Для небольших файлов файлы, отображенные в память, могут привести к пустой трате неиспользуемого пространства [8], поскольку карты памяти всегда выравниваются по размеру страницы, который в основном составляет 4 КБ. Следовательно, файл размером 5 КБ выделит 8 КБ, и, таким образом, 3 КБ будут потрачены впустую. Доступ к файлам, отображенным в память, быстрее, чем использование прямых операций чтения и записи, по двум причинам. Во-первых, системный вызов на порядки медленнее, чем простое изменение локальной памяти программы. Во-вторых, в большинстве операционных систем отображаемая область памяти на самом деле является кэшем страниц ядра (файловым кэшем), что означает, что в пользовательском пространстве не нужно создавать копии.

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

Возможным преимуществом файлов, отображенных в память, является «ленивая загрузка», то есть использование небольшого объема оперативной памяти даже для очень большого файла. Попытка загрузить все содержимое файла, который значительно больше объема доступной памяти, может вызвать сильное перенапряжение , поскольку операционная система считывает данные с диска в память и одновременно записывает страницы из памяти обратно на диск. Отображение памяти может не только полностью обойти файл подкачки, но и позволить загружать разделы размером с меньшую страницу по мере редактирования данных, аналогично подкачке по требованию, используемой для программ.

Процесс отображения памяти обрабатывается диспетчером виртуальной памяти , который является той же подсистемой, которая отвечает за работу с файлом подкачки . Отображенные в памяти файлы загружаются в память по одной странице за раз. Размер страницы выбирается операционной системой для максимальной производительности. Поскольку управление файлом подкачки является одним из наиболее важных элементов системы виртуальной памяти, загрузка разделов файла размером со страницу в физическую память обычно является очень высоко оптимизированной системной функцией. [9]

Типы

Существует два типа файлов, отображаемых в памяти:

Сохранялся

Сохраненные файлы связаны с исходным файлом на диске. Данные сохраняются в исходном файле на диске после завершения последнего процесса. Эти файлы, отображенные в память, подходят для работы с очень большими исходными файлами. [10]

Несохраняющийся

Несохраняемые файлы не связаны с файлом на диске. Когда последний процесс заканчивает работу с файлом, данные теряются. Такие файлы подходят для создания разделяемой памяти для межпроцессного взаимодействия (IPC). [10]

Недостатки

Основной причиной выбора отображенного в память файлового ввода-вывода является производительность. Тем не менее, могут быть компромиссы. Стандартный подход к вводу-выводу является дорогостоящим из-за накладных расходов на системные вызовы и копирования памяти. Подход к отображению в память имеет свою цену в виде незначительных сбоев страниц — когда блок данных загружен в кэш страниц , но еще не отображен в виртуальное пространство памяти процесса. В некоторых обстоятельствах отображенный в память файловый ввод-вывод может быть существенно медленнее стандартного файлового ввода-вывода. [11]

Другой недостаток файлов, отображаемых в память, связан с адресным пространством данной архитектуры : файл, размер которого превышает адресуемое пространство, может иметь только отображаемые части за раз, что усложняет его чтение. Например, 32-разрядная архитектура, такая как Intel IA-32, может напрямую адресовать только 4 ГиБ или меньшие части файлов. Еще меньший объем адресуемого пространства доступен отдельным программам — обычно в диапазоне от 2 до 3 ГиБ, в зависимости от ядра операционной системы. Однако этот недостаток практически устранен в современной 64-разрядной архитектуре.

mmap также имеет тенденцию быть менее масштабируемым, чем стандартные средства ввода-вывода файлов, поскольку многие операционные системы, включая Linux, имеют ограничение на количество ядер, обрабатывающих ошибки страниц. Чрезвычайно быстрые устройства, такие как современные твердотельные накопители NVM Express , способны сделать накладные расходы реальной проблемой. [12]

Ошибки ввода-вывода в базовом файле (например, его съемный диск отключен или оптический носитель извлечен, диск заполнен при записи и т. д.) при доступе к его отображенной памяти сообщаются приложению как сигналы SIGSEGV/SIGBUS в POSIX и структурированное исключение EXECUTE_IN_PAGE_ERROR в Windows. Весь код, обращающийся к отображенной памяти, должен быть готов обрабатывать эти ошибки, которые обычно не возникают при доступе к памяти.

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

Распространенное использование

Возможно, наиболее распространенным применением файла, отображенного в память, является загрузчик процессов в большинстве современных операционных систем (включая Microsoft Windows и Unix-подобные системы). Когда запускается процесс , операционная система использует файл, отображенный в память, чтобы перенести исполняемый файл вместе с любыми загружаемыми модулями в память для выполнения. Большинство систем отображения памяти используют технику, называемую подкачкой по требованию , когда файл загружается в физическую память подмножествами (по одной странице каждый), и только когда эта страница фактически упоминается. [13] В конкретном случае исполняемых файлов это позволяет ОС выборочно загружать только те части образа процесса, которые действительно необходимо выполнить.

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

Поддержка платформы

Большинство современных операционных систем или сред выполнения поддерживают некоторую форму доступа к файлам, отображенным в память. Функция mmap () , [14] которая создает отображение файла по заданному дескриптору файла, начальному расположению в файле и длине, является частью спецификации POSIX , поэтому широкий спектр систем, совместимых с POSIX, таких как UNIX , Linux , Mac OS X [15] или OpenVMS , поддерживает общий механизм для отображения файлов в память. Операционные системы Microsoft Windows также поддерживают группу функций API для этой цели, таких как CreateFileMapping() . [16]

Вот некоторые бесплатные переносимые реализации отображенных в память файлов для Microsoft Windows и POSIX-совместимых платформ:

Язык программирования Java предоставляет классы и методы для доступа к отображенным в памяти файлам, таким как FileChannel.

Язык программирования D поддерживает файлы, отображенные в память, в своей стандартной библиотеке (модуль std.mmfile). [21]

В Ruby есть gem (библиотека) под названием Mmap, которая реализует отображаемые в памяти файловые объекты.

Начиная с версии 1.6, Python включает модуль mmap в свою стандартную библиотеку. [22] Подробности модуля различаются в зависимости от того, является ли хост-платформа Windows или Unix-подобной .

Для Perl на CPAN доступно несколько модулей для отображения файлов памяти , например Sys::Mmap [23] и File::Map [24] .

В среде выполнения Microsoft .NET P/Invoke может использоваться для использования отображенных в память файлов напрямую через Windows API . Управляемый доступ (P/Invoke не обязательно) к отображенным в память файлам был представлен в версии 4 среды выполнения (см. Файлы, отображенные в память). Для предыдущих версий существуют сторонние библиотеки, которые предоставляют управляемые API. [25]

PHP поддерживал методы отображения памяти в ряде собственных функций доступа к файлам, таких как file_get_contents(), но удалил их в версии 5.3 (см. журнал изменений).

Для языка программирования R на CRAN существует библиотека bigmemory, которая использует библиотеку Boost и предоставляет отображаемые в память массивы непосредственно в R. Пакет ff предлагает отображаемые в память векторы, матрицы, массивы и фреймы данных.

Язык программирования J поддерживает файлы, отображенные в память, по крайней мере с 2005 года. Он включает поддержку упакованных массивов данных и файлов с одним типом данных. Поддержка может быть загружена из 'data/jmf' Движки баз данных Jdb и JD используют файлы, отображенные в память, для хранения столбцов.

Язык программирования Julia поддерживает ввод-вывод двоичных файлов, отображенных в память, через Mmapмодуль в стандартной библиотеке. [26]

Ссылки

  1. ^ Крис Зибенманн (7 июня 2018 г.). «История запутанного набора низкоуровневых способов выделения памяти в Unix».
  2. Разработка началась в 1969 году, поставки начались в 1976 году.
  3. ^ «Справочное руководство по вызовам монитора TOPS-20» (PDF) .
  4. ^ "Система 1022 База данных". У нас был кэш PMAP для файлового ввода-вывода (типа PA1050) в расширенных разделах.
  5. Декабрь 1988 г.
  6. ^ Джеффри Рихтер (октябрь 1995 г.). «Добавьте в свое приложение файлы с возможностью масштабирования и отображения в памяти». Microsoft Systems Journal . стр. 17–28.
  7. ^ Создание блока общей памяти, который может увеличиваться в размерах
  8. ^ "Использование mmap() для расширенного ввода-вывода файлов - BrainDump". Архивировано из оригинала 7 августа 2011 г. Получено 21 мая 2011 г.
  9. ^ , «Что могут предложить файлы, отображенные в память?».
  10. ^ ab "Memory-Mapped Files". Microsoft Developer Network . Получено 4 января 2016 г.
  11. ^ http://lists.freebsd.org/pipermail/freebsd-questions/2004-June/050371.html, чтение против mmap (или ввод-вывод против ошибок страниц) Мэтью Диллона
  12. ^ Папайаннис, Анастасиос; Ксантакис, Гиоргос; Салустрос, Гиоргос; Маразакис, Манолис; Билас, Ангелос (2020). Оптимизация ввода-вывода с отображением в памяти для быстрых устройств хранения данных. USENIX ATC '20. стр. 813–827.
  13. ^ "Пейджинг по требованию"
  14. Файлы с отображением памяти, архив 9 февраля 2007 г. на Wayback Machine
  15. ^ Apple – Mac OS X Leopard – Технологии – UNIX Архивировано 23 апреля 2009 г. на Wayback Machine
  16. ^ Функция CreateFileMapping (Windows)
  17. ^ «Совместное использование памяти между процессами: файлы, отображенные в памяти». Boost.org.
  18. ^ «Файлы, отображенные в памяти». Boost.org.
  19. ^ «Файлы, отображаемые в памяти для систем Windows и POSIX». SourceForge.
  20. ^ "cpp-mmf". GitHub.
  21. ^ "std.mmfile - D Programming Language". Digital Mars . Получено 4 декабря 2011 г.
  22. ^ "Новые модули в версии 1.6". Архивировано из оригинала 30 декабря 2006 г. Получено 23 декабря 2008 г.
  23. ^ "Модуль Perl Sys::Mmap".
  24. ^ "Файл::Map Perl Module".
  25. DotNet Архивировано 19 апреля 2010 г. на Wayback Machine
  26. ^ "Memory-mapped I/O · The Julia Language". docs.julialang.org . Получено 3 сентября 2023 г. .