首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >性能计数器值使用papi附加返回零。

性能计数器值使用papi附加返回零。
EN

Stack Overflow用户
提问于 2016-10-25 12:44:06
回答 1查看 858关注 0票数 1

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

代码语言:javascript
复制
#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);
}

我使用以下命令编译它:

代码语言:javascript
复制
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

我是这样运作的:

代码语言:javascript
复制
./pid_ex 7865

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

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

有人能让我知道它为什么会这样吗?为什么它没有得到价值?

EN

回答 1

Stack Overflow用户

发布于 2016-12-16 20:11:15

有几件事,我编译并试图运行您的代码。我是用-Wall编译的,您可能应该更改:

代码语言:javascript
复制
unsigned int l2miss = 0x0;
unsigned int data_all_from_l2 = 0x0;

转到

代码语言:javascript
复制
int l2miss = PAPI_NULL;
int data_all_from_l2 = PAPI_NULL;

所以你要去掉几个警告。

然后我试着运行你的代码,我得到了一个错误:

错误-7页测试c:行.

它是由以下函数调用发出的PAPI错误代码,从您的计算机不可用的给定事件开始:

代码语言:javascript
复制
if ( (retval = PAPI_event_name_to_code("PM_DATA_FROM_L2MISS",&l2miss)) != PAPI_OK)

代码语言:javascript
复制
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,一个只会睡觉和肉桂的程序(Linux )。

您可以看到,这些事件似乎是记录下来的: Firefox:

./papi-测试3922

事件集中有两个事件。

L2小姐为0

data_all_from_l2为0

L2小姐是130534

data_all_from_l2是104151

L2小姐是266181

data_all_from_l2是212618

..。

对于那些只是睡觉的节目,我得到了:

./papi-测试7870

事件集中有两个事件。

L2小姐为0

data_all_from_l2为0

L2小姐为0

data_all_from_l2为0

L2小姐为0

data_all_from_l2为0

..。

当您打印事件时,请忽略前面的字符串,因为我保留了您的字符串,尽管已注册的事件是不同的,我刚才提到了我以前可以在我的计算机上运行的事件。所以,我似乎不只是一直得到零,而是依赖于正在被观察的程序。

使用的PAPI版本为5.4.3。

另外,虽然我目前没有建议,但请注意while循环中的情况,因为可能会发生这样的情况:当您在循环中睡觉时,与PID相关的程序可以完成,它的PID可以重用并分配给另一个进程,您仍然可以满足条件,但在这种情况下,您可能看错了原来认为的程序。

也有一些讨论

50200000=1482029904使用像您这样的一些事件。

另外,您使用的事件是为power8机器(https://lkml.org/lkml/2015/5/27/858)定义的,因此您可能使用的是power8机器。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40240325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档