Промахи кэша (L1, L2, L3)
Пример кода с промахами кэш /src/examples/cache_miss.c:
#include <stdio.h>
#define SIZE 10000
int arr[SIZE][SIZE];
int main() {
long long sum = 0;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
sum += arr[j][i];
}
}
return 0;
}
Компилируем и запускаем профайлинг при помощи perf с флагом -e:
gcc -o2 -g cache_miss.c -o cache_miss
sudo perf stat -B -e cache-references,cache-misses,cycles,instructions,branches,faults,migrations ./cache_miss
Видим следующий вывод:
Performance counter stats for './cache_miss':
252,440,135 cache-references
3,536,534 cache-misses # 1.40% of all cache refs
1,227,589,321 cycles
1,606,273,789 instructions # 1.31 insn per cycle
145,190,445 branches
97,709 faults
2 migrations
0.332995043 seconds time elapsed
0.280862000 seconds user
0.051974000 seconds sys
Подробнее по каждой из команд perf -e:
cache-references– количество обращений доступа к памяти в КЭШе. Суммарно имеем252,440,135.cache-misses– количество кэш промахов, т.е. количество доступов к памяти, где небоходимо получить доступ из более памяти высокого уровня (high-levelилиRAM).3,536,534или1.40%от общего количества обращений.cycles– Общее количество циклов процессора (CPU), необходимых для работы программы. 1,227,589,321 циклов, время, которое процессор был активен.instructions– Количество выполненных инструкций (1,606,273,789,1.31insn per cycle).branches– calculates the number of branch instructions executed. Here, we have 193,719 branches, indicating the number of times the program changed its execution path.faults– adds up the number of page faults, which occur when a process tries to access a page of memory that is not currently mapped in its address space. Here, we have 1,523-page faults.migrations– quantifies the number of times a task is migrated between differentCPU cores, with2 migrationsin this example.time elapsed- line shows the total time taken for the./cache-missexample to execute, which is approximately0.332995043seconds.
Пример вывода с последовательным доступом к памяти (в строке):
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
sum += arr[i][j]; // Сначала суммируем строку, потом уже меняем столбец
}
}
Вывод perf:
Performance counter stats for './cache_miss':
14,890,250 cache-references
72,399 cache-misses # 0.49% of all cache refs
706,258,358 cycles
1,603,989,429 instructions # 2.27 insn per cycle
144,702,850 branches
97,711 faults
23 migrations
0.193752798 seconds time elapsed
0.134352000 seconds user
0.059155000 seconds sys