Code: Select all
// test.c
#include
#include
#include
int main(int argc, char **argv)
{
size_t n = 10000000;
double* arr;
if (posix_memalign((void**)&arr, 64, n * sizeof(double)) != 0) {
fprintf(stderr, "posix_memalign failed\n");
exit(1);
}
for (size_t i = 0; i < n; i += 64) {
_mm_clflush(&arr[i]);
}
for (size_t i = 0; i < n; i++) arr[i] = (double)i;
double sum = 0;
for (size_t i = 0; i < n; i++) sum += arr[i];
printf("Sum: %f\n", sum);
free(arr);
return 0;
}
Code: Select all
$ gcc -o test test.c
$ perf stat -e LLC-loads,LLC-loads-misses -- ./test
Sum: 49999995000000.000000
Performance counter stats for 'test':
94,765 LLC-loads:u
91,979 LLC-loads-misses:u # 97.06% of all LL-cache accesses
0.082974254 seconds time elapsed
0.047802000 seconds user
0.034893000 seconds sys
- Erstens sind die LLC-Lasten viel geringer als erwartet. Sollte es nahe bei 10000000/8 liegen (Cache-Zeile: 64 Byte)? Oder ist es möglich, dass nicht die gesamte Laufzeit profiliert wird?
- Zweitens und was noch wichtiger ist: Die Fehlerquote ist zu hoch. Ich gehe davon aus, dass jeder Lesefehler eine Cache-Zeile mit 8 Doubles mit sich bringt. Insgesamt sollte die Fehlschussquote also bei etwa 1/8 liegen? Eigentlich sollte es viel kleiner sein, da das Vorabholen in diesem Fall sehr hilfreich ist, oder?
Code: Select all
$ gcc --version
gcc (GCC) 15.2.0
Copyright (C) 2025 Free Software Foundation, Inc.
$ perf --version
perf version 4.18.0-553.84.1.el8_10.x86_64
$ lscpu | grep "Model name"
Model name: Intel(R) Xeon(R) Gold 6430
$ lscpu | grep "L3 cache"
L3 cache: 61440K
Mobile version