Я использую Cachegrind для получения количества промахов кеша статической программы, скомпилированной без libc (просто _start
, которая вызывает мою основную функцию, и системный вызов выхода в asm). Программа полностью детерминирована, инструкции и ссылки на память не меняются от одного запуска к другому. Кэш является полностью ассоциативным с LRU в качестве политики замены.
Однако я заметил, что количество промахов иногда меняется. В частности, количество промахов всегда одинаково, пока я не перейду в другой каталог:
% cache=8 && valgrind --tool=cachegrind --I1=$((cache * 64)),$cache,64 --D1=$((cache * 64)),$cache,64 --L2=262144,4096,64 ./adpcm
...
==31352== I refs: 216,145,010
...
==31352== D refs: 130,481,003 (95,186,001 rd + 35,295,002 wr)
==31352== D1 misses: 240,004 ( 150,000 rd + 90,004 wr)
==31352== LLd misses: 31 ( 11 rd + 20 wr)
И если я буду выполнять одну и ту же команду снова и снова, я буду получать одни и те же результаты. Но если я запущу эту программу из другого каталога:
% cd ..
% cache=8 && valgrind --tool=cachegrind --I1=$((cache * 64)),$cache,64 --D1=$((cache * 64)),$cache,64 --L2=262144,4096,64 ./malardalen2/adpcm
...
==31531== I refs: 216,145,010
...
==31531== D refs: 130,481,003 (95,186,001 rd + 35,295,002 wr)
==31531== D1 misses: 250,004 ( 160,000 rd + 90,004 wr)
==31531== LLd misses: 31 ( 11 rd + 20 wr)
И у меня даже другой результат из другого каталога.
Я также провел несколько экспериментов с инструментом Pin, и с этим мне не нужно менять каталог, чтобы получить другие значения. Но кажется, что набор возможных значений очень ограничен и точно такой же, как у Cachegrind.
Мой вопрос: каковы могут быть источники таких различий?
Моя первая подсказка заключается в том, что моя программа не выровнена в памяти таким же образом, и, как следствие, некоторые переменные, хранившиеся в той же строке в предыдущем запуске, больше не выровнены. Это также может объяснить ограниченное количество комбинаций. Но я думал, что этот cachegrind (и Pin) использовал виртуальные адреса, и я предполагаю, что ОС (Linux) всегда дает одни и те же виртуальные адреса. Любая другая идея?
Редактировать: Как вы можете догадаться, чтение LLd промахивается, программа использует только 31 различную строку кэша. Кроме того, кеш может содержать только 8 строк кеша. Таким образом, даже в реальности разницу нельзя объяснить тем, что кеш уже заполняется во второй раз (максимум, в L1 может оставаться только 8 строк).
Редактировать 2: отчет Cachegrind основан не на фактических промахах кэша (данных счетчиками производительности), а является результатом моделирования. По сути, он имитирует поведение кеша, чтобы подсчитать количество промахов. Поскольку последствия носят временный характер, это совершенно нормально и позволяет изменять свойства кеша (размер, ассоциативность).
Изменить 3: Я использую аппаратное обеспечение Intel Core i7 на Linux 3.2 x86_64. Флаги компиляции -static, а для некоторых программ -nostdlib (IIRC, меня сейчас нет дома).
__attribute__ (aligned (64))
. Однако это не решило мою проблему. - person Maxime Chéramy   schedule 02.07.2013kjournald
,kswapd
и т. д., которая записывает atime для некоторого каталога, в котором вы находитесь. Что-либо в системе может в конечном итоге вызвать попадание/промах кеша путем исключения некоторой случайной строки. Возможно, текущий каталог попадает в запись хеш-таблицы, которая использует одну и ту же строку. - person artless noise   schedule 05.07.2013