Наблюдение неожиданного результата для собственного счетчика событий P1I L1_MISS - PullRequest
1 голос
/ 09 июля 2019

Я использую PAPI для подсчета результатов доступа к кэш-памяти L1.В основном нативные события дают ожидаемые результаты, однако есть один случай, когда L1_MISS не является точным.У меня есть объект размером 64 и изменчивый массив из 100 000 элементов, как показано в коде:

typedef struct _object{
  int value;
  char pad[60];
} object;

#define arr_size 100000
volatile object  array [arr_size];

void * loop (int arg){
  /* Threads are set in NUMA2 */
  int temp;
  for(int i=0; i < arr_size; i++){
    temp = array[i].value;
  }
}

Я тестирую процессор Skylake с двумя узлами NUMA.Я отключил предварительных сборщиков.Компиляция с gcc -O3.Сценарий следующий: из основного процесса, заданного в NUMA1, я инициализирую массив и очищаю строки кэша.Затем я создаю 5 потоков, которые читают тот же массив из NUMA2, вызывая функцию loop .После того, как все они завершены, я зацикливаюсь на массиве из основного процесса, читая каждый элемент и отслеживаю результаты доступа к кэш-памяти L1:

int main(int argc, char* argv[]){
    /* Main thread is set in NUMA1 */
    /* Array is initialized and flushed from the cache*/
    /* 5 threads are created with pthread_create, that call loop function, 
       and waited to finish by calling pthread_join*/

 int tmp;
 /*Hardware counters are counted for this loop*/ 
 for(int i=0; i < arr_size; i++){
    tmp = array[i].value;
 }
}

Я читаю эти 5 собственных счетчиков событий:

MEM_INST_RETIRED.ALL_LOADS: 100095
L1D.REPLACEMENT: 100246 
MEM_LOAD_RETIRED.L1_HIT: 113 
MEM_LOAD_RETIRED.L1_MISS: 56 
MEM_LOAD_RETIRED.FB_HIT: 55 

Ожидалось, что L1_MISS увидит около 100 000, потому что элементы не выбираются в кеш, и это чтение в main должно вызвать промах.также ALL_LOADS не равно сумме трех счетчиков: L1_HIT + L1_MISS + FB_HIT.Несмотря на то, что L1D.REPLACEMENT, кажется, имеет смысл в этом случае, подсчитывая замены строк данных L1D, я не убежден в этом, поскольку он также учитывает предварительную выборку при включении.

Я не понимаю, что может бытьпричина того, что счетчик MEM_LOAD_RETIRED.L1_MISS не видит события, вызванные операцией чтения в main, только в этом конкретном сценарии.Как, например, если потоки из NUMA2 вместо чтения изменяют элемент массива, то для того же цикла я получаю L1_MISS: 99818. поэтому любое предложение будет полезным.Я попытался представить основной каркас кода.Если какие-либо части комментируемых пунктов важны, я также могу добавить их.

...