观察到PAPI的L1_MISS本机事件计数器的意外结果

时间:2019-07-09 12:07:47

标签: c caching x86 numa papi

我正在使用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;
  }
}

我正在使用两个NUMA节点的Skylake处理器进行测试。我禁用了预取器。用gcc -O3编译。场景如下:从NUMA1中设置的主进程中,我初始化一个数组并刷新高速缓存行。然后,我创建5个线程,这些线程通过调用 loop 函数从NUMA2中读取相同的数组。它们全部终止后,我从主进程中遍历一个数组,读取每个元素并监视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数据线替换看起来L1D.REPLACEMENT似乎很有意义,但我不认为L1D.REPLACEMENT在启用时也算预取。

仅在此特定情况下,我不理解MEM_LOAD_RETIRED.L1_MISS计数器看不到main中由读取操作引起的事件的原因是什么。例如,如果来自NUMA2的线程(而不是读取线程)修改数组元素,则对于同一循环,我会得到L1_MISS:99818。因此,任何建议都将有所帮助。 我试图提供代码的主要框架。如果评论点的任何部分很重要,我也可以添加它们。

0 个答案:

没有答案