mmap - это в основном программный доступ к подсистеме виртуальной памяти.
Если у вас есть, скажем, 1G-файл, и вы mmap его, вы получаете указатель на «весь» файл, как если бы он был в памяти.
Однако на этом этапе ничего не произошло, кроме фактической операции сопоставления резервирования страниц для файла в виртуальной машине. (Большой файл, тем длиннее операция отображения, конечно.)
Чтобы начать считывать данные из файла, вы просто получаете к нему доступ через указатель, который вы вернули в вызове mmap.
Если вы хотите «предварительно загрузить» части файла, просто зайдите в область, которую вы хотите предварительно загрузить. Убедитесь, что вы посещаете ВСЕ страницы, которые хотите загрузить, поскольку виртуальная машина загружает только страницы, к которым вы обращаетесь. Например, скажем, в вашем 1G-файле у вас есть 10-мегабайтная «индексная» область, на которую вы хотели бы отобразить. Самый простой способ - просто «прогуливать свой индекс» или любую имеющуюся у вас структуру данных, позволяя странице VM при необходимости. Или, если вы «знаете», что это «первые 10 МБ» файла, и что размер вашей страницы для вашей виртуальной машины составляет, скажем, 4K, тогда вы можете просто нанести указатель mmap на указатель символа и просто перебрать страницы.
void load_mmap(char *mmapPtr) {
// We'll load 10MB of data from mmap
int offset = 0;
for(int offset = 0; offset < 10 * 1024 * 1024; offset += 4 * 1024) {
char *p = mmapPtr + offset;
// deref pointer to force mmap load
char c = *p;
}
}
Что касается L1 и L2 кэшей, ММАП не имеет ничего общего с тем, что это все о том, как получить доступ к данным.
Поскольку вы используете базовую систему VM, все, что обращается к данным в блоке mmap'd, будет работать (когда-либо с сборки).
Если вы не изменяете данные mmap'd, виртуальная машина автоматически удалит старые страницы с новыми страницами. Если вы действительно измените их, VM вернет вам эти страницы.
Не будет обугливается "с = * р" быть оптимизированы прочь? Должен ли c быть объявлен изменчивым? –
В последних версиях Linux вы можете установить MAP_POPULATE в аргументе flags в mmap(), и страницы будут вытащены до того, как будет возвращен вызов. Это блокирует вызов в течение определенного периода времени, который является некоторой функцией размера файла, поэтому запуск функции load_mmap() в отдельном потоке может повысить производительность, если есть другая работа, которая может выполняться параллельно, прежде чем содержимое файла потребуется для чтения, тем более, что большая часть работы выполняется на стороне ядра. –
Разве «mlock» не загружает страницы? –