如何定义要由PAPI衡量的用户定义事件?

时间:2019-03-05 12:19:11

标签: assembly profiling papi

当今大多数处理器都配备了硬件性能计数器。此类计数器可用于对微体系结构事件进行计数,以便分析目标程序以提高其性能。通常,分析和分析是这些计数器的主要目标。

根据文献中提出的研究论文,这些计数器缺乏准确性。例如,如果我们要计算给定代码中已退休指令的数量,则该值可能会从运行更改为另一个扰动问题。 已经讨论了一些准则以提高测量精度。监视多个事件可以更好地了解正在执行的程序,从而提高测量精度。

User-defined events for hardware performance monitoring的作者已经提出了一种新方法,使用户能够定义自己的事件以供PAPI(Performance API)使用,PAPI是一种广泛用于轻松访问硬件性能计数器的基础结构办法。不幸的是,本文没有详细解释我们如何定义用户定义的事件以及如何在程序中使用它们。

例如(基于PAPI),我试图定义一个涉及 n 本机/预设事件的新事件,例如(PAPI_TOT_INS,PAPI_BR_TKN和PAPI_STR_INS),然后将其用作单个事件我的代码。


编辑:

基于上述论文,我设置了环境变量PAPI USER_EVENTS FILE来指示包含用户定义事件的文件,并且该文件将通过调用PAPI_library_init函数来启动和解析。 event_file非常简单(仅用于测试):

#define a 5

tot_ins, PAPI_TOT_CYC|a|*

我的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <papi.h>


int main(int argc, char** argv) {

long_long val[10000]; 

 int EventSet = PAPI_NULL;
 long_long values[1];

PAPI_library_init(PAPI_VER_CURRENT);
PAPI_create_eventset(&EventSet);

//tot_ins is the name of the event defined in event-file
int counter_code;
PAPI_event_name_to_code("tot_ins",& counter_code);
printf("code =%x\n",counter_code);

PAPI_add_event(EventSet,counter_code);

int k;
int index=0;

for (k=0; k<5; k++)
{  

       PAPI_start(EventSet);

int i;

for (i=0; i<100; i++)
{
int x;
int y;
int z;

x=i+2;
y=x+i/15;
z=x/y;

}

       PAPI_read(EventSet, values) ;
       //printf("test number  %d        %lld \n",k,values[0]);
       printf("%lld\n",values[0]);
       PAPI_stop(EventSet, values) ;

printf("\n---------------------------------- \n");
 }// end k 

}

但是,对于计数和计数器代码而言,输出似乎很奇怪

我在文本文件中定义了一个简单事件(在Linux Ubuntu OS中),并设置了环境变量以指示该文件。但是在代码中,两者

PAPI_event_name_to_code("tot_ins",& counter_code); //(retvalue=-7)

PAPI_add_event(EventSet,counter_code); //(retvalue=-10)

返回不等于PAPI_OK的值。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,并尝试设置环境变量PAPI_USER_EVENTS_FILE,但一开始它不起作用。然后我发现我设置了错误的PMU名称,以及如何获取正确的PMU名称。我的IvyBridge CPU上的最小工作示例:

# sandy/ivybridge
CPU,snb
CPU,snb_ep
CPU,ivb
CPU,ivb_ep
EVENT,USER_CPS,DERIVED_PS,PAPI_TOT_CYC,PAPI_TOT_INS,NOTE,'instructions per second'

错误是我获取了pmu_name文件的内容:

cat /sys/devices/cpu/caps/pmu_name
ivybridge

我查找了 papi_source_dir / src / papi_events.csv 中使用的PMU名称值,然后它起作用了。可能有一种更好的方法来查询PAPI使用的PMU名称。

我认为应该改进有关此功能的文档,并且手册页有些误导。


当前不支持PAPI_set_opt(6.0.0.1)作为提供用户定义的事件文件的方式:(来自papi_preset.c)

  • 预置事件定义有三种可能的输入源。该代码将首先查找环境变量“ PAPI_CSV_EVENT_FILE”。如果找到,则将其值用作获取预设信息的路径名。如果找不到,则代码将查找包含预设事件的内置表。如果内置表不是在PAPI构建期间创建的,则代码将构建形式为“ PAPI_DATADIR / PAPI_EVENT_FILE”的路径名。这些都是构建变量,可以在构建PAPI的过程中为PAPI_DATADIR变量赋予一个值,并且PAPI_EVENT_FILE变量的硬编码值为“ papi_events.csv”。
  • 只有一种定义用户事件的方法。该代码将查找环境变量“ PAPI_USER_EVENTS_FILE”。如果找到,则将其值用作包含用户事件定义的文件的路径名。完成对PAPI_library_init的调用后,此文件中定义的事件将添加到PAPI已知的事件中。
  • 待办事项:
  • 通过调用PAPI_set_opt(PAPI_USER_EVENTS_FILE)来恢复指定用户定义的事件文件的功能。
  • 这需要弄清楚如何将pmu名称(可以使用组件0的默认pmu)传递给该函数。
  • 当前PAPI中其他地方的代码将预设事件和用户事件可能依赖的事件限制为组件0已知的那些事件。可以放宽此限制以允许来自不同组件的事件。但是,由于必须将任何派生事件使用的所有事件都添加到同一事件集中,因此始终要求给定派生事件使用的所有事件必须来自同一组件。