Когда и как происходит смятие памяти mmap'ed?
В моем понимании, mmap'ing файла, который помещается в ОЗУ, будет похож на файл в памяти.
Скажем, что у нас есть 16G RAM, и мы сначала mmap 10G файл, который мы используем некоторое время. Это должно быть достаточно эффективным с точки зрения доступа. Если мы тогда mmap второй 10G файл, это приведет к тому, что первый будет заменен? Или его части? Если да, когда это произойдет? При вызове mmap или при доступе к области памяти только что загруженного файла?
И если мы хотим снова получить доступ к памяти указателя для первого файла, это заставит его загрузить файл подкачки снова? Итак, скажем, мы чередуем чтение между памятью, соответствующей первому файлу и второму файлу, что приведет к катастрофической производительности?
Наконец, если это правда, было бы лучше, чтобы mmap несколько файлов меньшего размера?
Ответы
Ответ 1
Как уже обсуждалось, ваш файл будет доступен на страницах; на архитектуре x86_64 (и IA32), страница обычно составляет 4096 байт. Итак, очень мало, если какой-либо файл будет загружен в mmap. При первом доступе к какой-либо странице в любом файле ядро сгенерирует ошибку страницы и загрузите часть своего файла. Ядро может предварительно выбирать страницы, поэтому может загружаться более одной страницы. Независимо от того, зависит ли это от вашего шаблона доступа.
В целом, ваша производительность должна быть хорошей, если ваш рабочий набор подходит в памяти. То есть, если вы только регулярно подключаете 3G файл к обоим файлам, если у вас есть 3G-RAM, доступный вашему процессу, все должно быть в порядке.
В 64-битной системе нет причины разбить файлы, и все будет в порядке, если нужные вам части будут соответствовать ОЗУ.
Обратите внимание, что если вы mmap существующего файла, для чтения этого файла не потребуется пространство подкачки. Когда объект поддерживается файлом файловой системы, ядро может читать из этого файла, а не подкачки. Однако, если вы укажете MMAP_PRIVATE в своем вызове mmap, может потребоваться пространство подкачки для хранения измененных страниц, пока вы не вызовете msync.
Ответ 2
В вашем вопросе нет окончательного ответа, так как обмен файлами в ядре также выполняется, и каждое ядро будет иметь другую реализацию (и сам linux предлагает разные профили в зависимости от вашего использования, RT, рабочего стола, сервера...)
Вообще говоря, все, что вы загружаете в память, выполняется с помощью страниц, поэтому ваш файл в формате mmap в памяти загружается (и выгружается) между страницами между всеми уровнями памяти (кэши, оперативная память и своп).
Затем, если вы загрузите два 10 ГБ данных в память, у вас будут части как между ОЗУ, так и вашей Swap, и ядро попытается сохранить в RAM страницы, которые вы, вероятно, будете использовать сейчас, и угадать, что вы будете загружать дальше.
Это означает, что если вы действительно произвольно получаете доступ к нескольким байтам данных в обоих файлах, то вам следует ожидать ужасающей производительности, если вы одновременно получаете доступ к смежным фрагментам из обоих файлов, вы должны ожидать достойную производительность.
Вы можете прочитать более подробную информацию о пейджинге ядра в теории виртуальной памяти: