3

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

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

用于硬件性能监控的用户定义事件的作者提出了一种新方法,使用户能够定义自己的事件以供 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 

}

但是,计数和 counter_code 的输出似乎都很奇怪

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

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

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

返回一个不等于 PAPI_OK 的值。

任何帮助将不胜感激。

4

1 回答 1

2

万一其他人迷路并降落在这里:

我有同样的问题,并尝试设置环境变量PAPI_USER_EVENTS_FILE,但它一开始没有用。然后我发现我设置了错误的 PMU 名称以及如何获得正确的 PMU 名称。我的 IvyBridge CPU 上的最小工作示例,它定义了一个别名PAPI_DP_OPS

# ivybridge
CPU,ivb
EVENT,USER_DP_OPS,NOT_DERIVED,PAPI_DP_OPS,NOTE,'FLOPS'

错误是我使用了 pmu_name 文件的内容,而不是 PAPI 使用的 pmu 名称:

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

papi_component_avail您可以使用手册页中给出的查询可用的 PMU 名称man PAPI_derived_event_files。该文件papi_events.csv(见下文)包含 PAPI 使用的预设事件和所有 PMU 名称。手册页还描述了用户事件文件的语法。papi_avail如果有效,将显示添加的用户事件。

但是,我认为这是错误的:例如,别名显示 dp 操作的完全不同的数字。我认为应该改进有关此功能的文档,并且用户定义的派生事件文件的手册页不包含如何指定文件。


PAPI_set_opt,如参考论文中所描述的替代方法,目前 (6.0.0.1) 不支持作为指定用户定义事件文件的一种方式,并将返回错误号(错误字符串“null”):(来自 papi_preset.c)

  • 预设事件定义有三种可能的输入源。代码将首先查找环境变量“PAPI_CSV_EVENT_FILE”。如果找到,其值将用作获取预设信息的路径名。如果未找到,代码将查找包含预设事件的内置表。如果在构建 PAPI 期间未创建内置表,则代码将构建“PAPI_DATADIR/PAPI_EVENT_FILE”形式的路径名。其中每一个都是构建变量,PAPI_DATADIR 变量可以在构建时配置 PAPI 期间被赋予一个值,并且 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 已知的事件。这可能会放宽以允许来自不同组件的事件。但是由于任何派生事件使用的所有事件都必须添加到同一个事件集中,因此始终要求给定派生事件使用的所有事件必须来自同一个组件。
于 2020-12-17T13:23:58.067 回答