Я наблюдал странное поведение, когда большой файл с отображенной памятью (2 ГБ) не берет реальную физическую память, когда я читаю из нее, но делает, когда я начинаю писать в нее.
int err = 0;
int fd = open("large_file", O_RDWR);
if (fd == -1) {
return errno;
}
void *map = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
if (map == MAP_FAILED) {
err = errno;
goto out;
}
for (unsigned int i = 0; i < 2 << 30; i += PAGE_SIZE) {
volatile uint8_t val = 0xff;
// val = ((volatile uint8_t *) map)[i]; /* Doesn't take actual memory */
// ((volatile uint8_t *) map[i]) = val; /* Takes actual memory */
}
while (1)
sleep(10);
out:
if (fd != -1)
close(fd);
if (map != MAP_FAILED)
munmap(map, size);
return err;
Это снимок экрана htop, когда я ЧИТАЙ из сопоставленного файла (см. "Check")
ЭтоСнимок экрана htop, когда я ЗАПИСИ в сопоставленный файл (посмотрите на "check"
Мой ноутбук в значительной степени бездействует, ничто иное не может взять физическую оперативную память, кроме моего процесса тестирования, поэтомувы можете видеть, что когда я записываю в сопоставленный файл, он фактически занимает 2 ГБ (копирование при записи), а при чтении - нет. RES-SHR также подходит для обоих моих случаев.
Я могуне объясните это .. ядро отображает новую страницу независимо от того, является ли она чтением или записью в физическую ОЗУ. Если она отсутствует, она должна отображаться и занимать фактическую ОЗУ после исключения сбоя страницы. Отображенный файл не сопоставлен с другими процессами, поэтому он не используется совместно. Процесс тестирования является единственным и первым, который отображает файл в память.
РЕДАКТИРОВАТЬ: я добавил (volatile), чтобы компилятор не оптимизировал критический код.сть.Этот конкретный фрагмент ассемблерного кода является результатом чтения из отображенного в память файла:
mov BYTE PTR [rbp-0xbd],0xff /* volatile uint8_t val = 0xff; */
mov edx,DWORD PTR [rbp-0xbc]
mov rax,QWORD PTR [rbp-0xb0]
add rax,rdx
movzx eax,BYTE PTR [rax]
mov BYTE PTR [rbp-0xbd],al /* val = ((volatile uint8_t *)map)[i]; */
add DWORD PTR [rbp-0xbc],0x1000 /* i += PAGE_SIZE; */
Есть мысли?