Я предполагаю, что это из-за какого-то кеша, но мне все еще интересно.
При использовании memset во второй раз в той же памяти код выполняется намного быстрее.
возьмем этот кусок кода:
> for_stackoverflow.c
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
long long size = 1 << 29;
int i;
char * mem;
clock_t start, end;
double how_long;
mem = malloc(size);
start = clock(); {
memset(mem, 0xde, size);
} end = clock();
how_long = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("%f\n", how_long);
start = clock(); {
memset(mem, 0xad, size);
} end = clock();
how_long = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("%f\n", how_long);
free(mem);
return 0;
}
и скомпилируйте его без какой-либо оптимизации (иначе memset будет пропущен, я думаю, это потому, что он не появится при выполнении objdump objdump -dw a.out
)):
$ gcc -O0 for_stackoverflow.c
результат на моей машине (gnu / linux ubuntu 20.04 intel i5):
$ ./a.out
0.244824
0.044119
... И второй memset работал быстрее, чем первый.
Я могу получить любопытный результат, например, если поставить половину размера, получится ровным:
memset(mem, 0xad, size); -> memset(mem, 0xde, size/2);
memset(mem, 0xad, size); -> memset(mem, 0xad, size);
$./a.out
0.145827
0.141934
Это заставляет меня думать, что повторный запуск памяти намного быстрее.
Я не понимаю, какая оптимизация происходит в этом примере. Есть ли кто-нибудь, кто знает, что происходит?
Помощь будет очень признательна
-O0
) не имеет особого значения; Подавляющее большинство работы происходит в написанной вручную библиотечной функции asm. - person Peter Cordes   schedule 27.11.2020-O3
может даже оказаться контрпродуктивным, поскольку компилятор может оптимизировать вызовmemset()
. Изменить: время сокращается до нескольких мкс для обеих частей с-O1
. - person 12431234123412341234123   schedule 27.11.2020malloc
возвращает память, на которую больше ничего не указывает, поэтому он может доказать, что хранилища мертвы, и оптимизировать их.gcc -O3 -fno-builtin-malloc
может генерировать вызовы функций, которые вы хотите протестировать, с более эффективными вызовами между ними, если первый набор памяти все еще не обрабатывается как мертвые хранилища. (Вероятно, нет, потому что эта программа выполняет некоторые вызовы функций между двумя синхронизированными регионами.) - person Peter Cordes   schedule 27.11.2020