当前位置: 首页 > 工具软件 > PAPI > 使用案例 >

PAPI:使用PAPI对程序进行性能分析(1)

越嘉石
2023-12-01

PAPI 是非常好的性能测试工具,使用十分方便。对于分析程序的性能提供很好的依据。

下面对使用PAPI 做一个小结。

(1)Build PAPI on Linux

在PAPI主站上下载最新的tar包,解压缩,然后进入到papi文件夹下的src文件夹下:

./configure–prefix=${PAPI_HOME}

make

make test

make install

设置环境变量:   PATH= ${PAPI_HOME}/bin:${PATH}

                               LD_LIBRARY_PATH=${PAPI_HOME}/lib:${LD_LIBRARY_PATH}

编译选项:           -I ${PAPI_HOME}/include -lpapi -L ${PAPI_HOME}/lib

 

Userful binaries:

papi_avail:          查看当前机器上可以选择测试的性能选项。

papi_meminfo:  查看TLB,Cache信息

papi_cost:              查看papi开销

(2)使用PAPI

使用PAPI需要在源码进行插桩, 但是非常简单,一共5个阶段

初始化papi

/* Initialize the PAPI library */
if (PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT)
exit(1);
/*Initialize the papi thread support:初始化线程支持,不使用线程这个部分可以省略。*/
if (PAPI_thread_init(pthread_self) != PAPI_OK)
    exit(1);

创建事件集

事件就是指的是你要测试哪些性能数据,可以选择的性能指标通过papi_avail可以查看。例如L1,L2,L3 cache miss,clock cycle等等。

/* Create an EventSet */
int EventSet = PAPI_NULL; 
int retval = PAPI_create_eventset (&EventSet);
assert(retval==PAPI_OK);

/* Add an event*/
retval = PAPI_add_event(EventSet, PAPI_L3_TCM);
assert(retval==PAPI_OK);

有些Event是支持一起测试的,如果想一次测试多个数据,再增加一个Event,至于哪些可以一起测试,需要自我探索一下。有一些可以一起测,有些事不可以的。

/*Add another event*/
retval = PAPI_add_event(EventSet, PAPI_TOT_INS);
assert(retval==PAPI_OK);

开始计数

/* Start counting events */
if (PAPI_start(EventSet) != PAPI_OK)
retval = PAPI_start (EventSet);
assert(retval==PAPI_OK);

读取数据

long long values1[2];
long long values2[2];
PAPI_read(EventSet, values1);
assert(retval==PAPI_OK);

//Do something

/* Stop counting events */
retval = PAPI_stop (EventSet,values2);
assert(retval==PAPI_OK);

得到结果

L3_TCM: values2[0] – values1[0]   L3 cache miss

TOT_INS:   values2[1] – values1[1]  total instruction counts

释放事件,清理工作

/* Clean up EventSet */
if (PAPI_cleanup_eventset(EventSet) != PAPI_OK)
   exit(-1);

/* Destroy the EventSet */
if (PAPI_destroy_eventset(&EventSet) != PAPI_OK)
  exit(-1);

/* Shutdown PAPI */

PAPI_shutdown();

(3)一个简单的例子

simple_papi.c

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

int main() {

	int EventSet;
	int i, sum;
	long_long values[2], values1[2], values2[2];

	if (PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT)
		exit(-1);

	EventSet = PAPI_NULL;
	if (PAPI_create_eventset(&EventSet) != PAPI_OK)
		exit(-1);

	if (PAPI_add_event(EventSet, PAPI_TOT_INS) != PAPI_OK)
		exit(-1);
	if (PAPI_add_event(EventSet, PAPI_L1_DCM) != PAPI_OK)
		exit(-1);

	if (PAPI_start(EventSet) != PAPI_OK)
		exit(-1);

	if (PAPI_read(EventSet, values1) != PAPI_OK)
		exit(-1);

	for (i=0;i<10000;i++)
		sum+=i;

	if (PAPI_stop(EventSet, values2) != PAPI_OK)
		exit(-1);

	if (PAPI_cleanup_eventset(EventSet) != PAPI_OK)
		exit(-1);

	if (PAPI_destroy_eventset(&EventSet) != PAPI_OK)
		exit(-1);

	PAPI_shutdown();
	/* Get value */
	values[0]=values2[0]-values1[0];
	values[1]=values2[1]-values1[1];
	printf("TOT_INS:%lld\nL1_DCM: %lld\n",values[0], values[1]);
	return 0;
}
编译:

gcc -o simple_papi  simple_papi.c -I ${PAPI_HOME}/include -L ${PAPI_HOME}/lib -lpapi -Wall -O3

运行结果:

TOT_INS:820
L1_DCM: 11

 类似资料: