gpt4 book ai didi

c - 使用 papi attach 性能计数器值返回零

转载 作者:太空宇宙 更新时间:2023-11-04 01:21:58 25 4
gpt4 key购买 nike

我正在尝试使用 PAPI 读取硬件性能计数器,并且我编写了以下代码:

#include <stdio.h>
#include <stdlib.h>
#include "papi.h" /* This needs to be included every time you use PAPI */
#include <unistd.h>

#define NUM_EVENTS 2
#define ERROR_RETURN(retval) { fprintf(stderr, "Error %d %s:line %d: \n", retval,__FILE__,__LINE__); exit(retval); }

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

if(argc<=1) {
printf("Pid is not provided, I will die now :( ...");
exit(1);
} //otherwise continue on our merry way....

int EventSet = PAPI_NULL;
int tmp, i;
/*must be initialized to PAPI_NULL before calling PAPI_create_event*/

long long values[NUM_EVENTS];
/*This is where we store the values we read from the eventset */

/* We use number to keep track of the number of events in the EventSet */
int retval, number;

char errstring[PAPI_MAX_STR_LEN];
pid_t pid = atoi(argv[1]);

unsigned int l2miss = 0x0;
unsigned int data_all_from_l2 = 0x0;
/***************************************************************************
* This part initializes the library and compares the version number of the*
* header file, to the version of the library, if these don't match then it *
* is likely that PAPI won't work correctly.If there is an error, retval *
* keeps track of the version number. *
***************************************************************************/


if((retval = PAPI_library_init(PAPI_VER_CURRENT)) != PAPI_VER_CURRENT )
ERROR_RETURN(retval);


/* Creating the eventset */
if ( (retval = PAPI_create_eventset(&EventSet)) != PAPI_OK)
ERROR_RETURN(retval);


/* Add Native event to the EventSet */
// if ( (retval = PAPI_event_name_to_code("PM_DATA_FROM_L2MISS",&l2miss)) != PAPI_OK)
if ( (retval = PAPI_event_name_to_code("PM_L3_CO_MEM",&l2miss)) != PAPI_OK)
ERROR_RETURN(retval);

if ( (retval = PAPI_add_event(EventSet, l2miss)) != PAPI_OK)
ERROR_RETURN(retval);

/* Add Native event to the EventSet */
if ( (retval = PAPI_event_name_to_code("PM_DATA_ALL_FROM_L2",&data_all_from_l2)) != PAPI_OK)
ERROR_RETURN(retval);

if ( (retval = PAPI_add_event(EventSet, data_all_from_l2)) != PAPI_OK)
ERROR_RETURN(retval);


/* get the number of events in the event set */
number = 0;
if ( (retval = PAPI_list_events(EventSet, NULL, &number)) != PAPI_OK)
ERROR_RETURN(retval);

printf("There are %d events in the event set\n", number);


retval = PAPI_attach( EventSet, ( unsigned long ) pid );
if ( retval != PAPI_OK )
ERROR_RETURN(retval);


/* Start counting */

if ( (retval = PAPI_start(EventSet)) != PAPI_OK)
ERROR_RETURN(retval);

while(kill(pid,0)==0)
{
if ( (retval=PAPI_read(EventSet, values)) != PAPI_OK)
ERROR_RETURN(retval);

printf("The L2 Miss are %lld \n",values[0]);
printf("The data_all_from_l2 are %lld \n",values[1]);
sleep(1);
}//while

/* Stop counting and store the values into the array */
if ( (retval = PAPI_stop(EventSet, values)) != PAPI_OK)
ERROR_RETURN(retval);

printf("Total L2 Miss are %lld \n",values[0]);
printf("Total data_all_from_l2 are %lld \n",values[1]);


/* free the resources used by PAPI */
PAPI_shutdown();

exit(0);
}

我使用以下命令编译它:

gcc -I/apps/PAPI/5.5.0/GCC/5.4.0/CUDA/8.0/include -O0 pid_ex.c  -L/apps/PAPI/5.5.0/GCC/5.4.0/CUDA/8.0/lib -lpapi -o pid_ex

然后我这样运行它:

./pid_ex 7865

其中 7865 是正在运行的进程的进程 ID。

问题是它显示的是零值而不是计数器值。

谁能告诉我为什么会这样?为什么它没有获取值?

最佳答案

一些事情,我编译并尝试运行您的代码。我用 -Wall 编译,你可能应该更改:

unsigned int l2miss = 0x0;
unsigned int data_all_from_l2 = 0x0;

进入

int l2miss = PAPI_NULL;
int data_all_from_l2 = PAPI_NULL;

这样你就可以去掉一些警告了。

然后我试着运行你的代码,但我收到了这个错误:

Error -7 papi-test.c:line ...

这是当给定事件对您的机器不可用时的 PAPI 错误代码,由以下函数调用发出:

if ( (retval = PAPI_event_name_to_code("PM_DATA_FROM_L2MISS",&l2miss)) != PAPI_OK)

if ( (retval = PAPI_event_name_to_code("PM_DATA_ALL_FROM_L2",&data_all_from_l2)) != PAPI_OK)

鉴于此,我检查了哪些事件可用于我的机器并得到以下信息:

$ papi_avail

并且您的事件不适合我。因此,为了测试您的代码,我更改了要记录的事件并将它们设置为:

PAPI_L1_DCM

PAPI_L2_DCM

分别代表L1和L2数据缓存未命中。然后我针对四个程序运行您的程序:firefox、java、一个只休眠的程序和 cinnamon (Linux Mint)。

好像记录了事件,如你所见:火狐:

./papi-test 3922

事件集中有2个事件

L2 Miss为0

data_all_from_l2 为 0

L2小姐是130534

data_all_from_l2 是 104151

L2小姐是266181

data_all_from_l2 是 212618
...

对于刚刚休眠的程序,我得到:

./papi-test 7870

事件集中有2个事件

L2 Miss为0

data_all_from_l2 为 0

L2 Miss为0

data_all_from_l2 为 0

L2 Miss为0

data_all_from_l2为0
...

请忽略数字之前打印的字符串,因为我在打印事件时保留了您的字符串,尽管注册的事件不同,我刚刚在上面提到了哪些我曾经能够在我的计算机上运行它。所以看起来我不仅总是得到零,而且取决于正在观察的程序。
使用的PAPI版本是5.4.3。
此外,虽然我目前没有建议,但要注意你检查的 while 循环中的条件,因为当你在循环中 sleep 时可能会发生与 PID 关联的程序可能会完成并且它的 PID 被重用并分配给另一个过程,你仍然会满足条件,但在这种情况下,你可能会看到你最初认为的错误程序。
还有一些讨论
https://lists.eecs.utk.edu/pipermail/ptools-perfapi/2016-October/004060.html?cm_mc_uid=57211302537614804702521&cm_mc_sid_50200000=1482029904使用像您这样的事件。
另外,您使用的事件是为 power8 机器 ( https://lkml.org/lkml/2015/5/27/858 ) 定义的,因此您可能使用的是 power8 机器。

关于c - 使用 papi attach 性能计数器值返回零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40240325/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com