Я провел тест производительности при записи 128 миллионов ints в память, выделенную с помощью malloc, и сопоставленному файлу памяти (с поддержкой файла на диске) с помощью mmap ... Я ожидал, что результаты будут несколько похожими на я понимаю, что при записи в сопоставленный файл памяти данные сначала записываются в память, а pdflush записывает на диск в фоновом режиме (с частотой, которую можно настроить). С malloc запись 128M ints заняла 0,55 секунды; mmap занял 1,9 секунды.malloc vs mmap performance
Так что мой вопрос: почему разница. Мои инициалы были в том, что pdflush переполняет автобус или что, когда pdflush обращается к памяти, он блокирует записи ... Однако запуск версии mmap во второй раз вызвал результат .52 секунд (из-за кэширования), который приводит мне кажется, что каждая страница за mmap не выделяется до тех пор, пока она не будет записана (несмотря на то, что она зарезервирована для вызова в mmap) ... также я понимаю, что память, созданная malloc, фактически не выделяется до первой записи. . Возможно, первоначальное различие состояло в том, что после первоначальной записи в память с помощью malloc весь кусок выделяется и с mmap, каждый раз, когда записывается новая страница, os должен сначала выделить его?
UPDATE:
ОС: релиз CentOS Linux 7.0.1406 (ядро) ядро : 3.10.0-123.el7.x86_64 НКУ: 4.8.2
КОД:
int* pint = malloc(128000000 * sizeof(int));
int* pint_copy = pint;
clock_t start = clock();
int i;
for(i = 0; i < 128000000; ++i)
{
*pint++ = i;
}
clock_t end = clock();
double cpu_time_used = ((double) (end - start))/CLOCKS_PER_SEC;
printf("%f\n", cpu_time_used);
free(pint_copy);
против
int fd = open("db", O_RDWR | O_CREAT, 0666);
const size_t region_size = ((512000000/sysconf(_SC_PAGE_SIZE)) + 1) * sysconf(_SC_PAGE_SIZE);
int return_code = ftruncate(fd, region_size);
if (return_code < 0)
printf("mapped memory file could not be truncated: %u\n", return_code);
int* pint = mmap(NULL, region_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
int* pint_copy = pint;
close(fd);
clock_t start = clock();
int i;
for(i = 0; i < 128000000; ++i)
{
*pint++ = i;
}
clock_t end = clock();
double cpu_time_used = ((double) (end - start))/CLOCKS_PER_SEC;
printf("%f\n", cpu_time_used);
fgetc(stdin);
munmap(pint_copy, region_size);
ДОБАВЛЕНИЕ:
int z = 512;
while(z < 128000000)
{
pint[z] = 0;
z += 1024;
}
ДО:
clock_t start = clock();
Производит .37 секунд для обоих испытаний, что приводит меня к мысли, что «трогательные» на каждой странице приводит к тому, ОС выделить физическую память (как для mmap и malloc) ... это также может быть частично связано с тем, что «прикосновение» к страницам перемещает часть памяти в кеш-память ... знает ли кто-нибудь, если во время интенсивной записи в память (в течение длительного периода времени) pdflush блокирует или записывается медленная память?
Это очень специфичный для ОС (и специфичный для компилятора), но вы не говорите, что используете. – Hogan
Malloc, скорее всего, использует mmap, а также внутренне, проверьте с помощью strace. Скорее всего, это сопоставление объекта общей памяти (см. Shm_open, в недавних Linuxes это открывает файл в/dev/shm, используя tmpfs). Также флаг MMAP_POPULATE в mmap, вероятно, связан. –
Так много переменных, которые могут повлиять на это: другие вещи, количество процессоров, доступность памяти, прерывания, фоновые операции ввода-вывода, считывание вперед и/или предварительные ошибки, фактическое использование 'mmap()' (т. map '/ dev/zero' или реальный файл или что-то еще, и если реальный файл, он существовал до того, как он был назначен или должен быть выделен) и так далее ... – twalberg