PAPI性能测试工具的安装、使用及实例

一、PAPI简介

PAPI是田纳西大学创新计算实验室开发的一组可以在多个处理器平台上对硬件性能计数器进行访问的标准接口,它的目标是方便用户在程序运行时监测和采集由硬件性能计数器记录的处理器事件信息。用户可以使用其提供的high/low api对程序某一段的使用时钟周期数,执行指令数,L1/L2 cache miss/access数,TLB miss数等等都统计出来,使用户能够直观的了解到程序的局部性如何。

不同的处理器会根据自身的体系结构特征定义出不同的处理器事件集合,在 PAPI 中这些事件被称为原生事件(Native Event)。同时,不同的处理器也会具有不同数量的硬件性能计数器,而在任意时刻一个计数器只能对一个指定的原生事件进行监测。考虑到事件监测和性能分析的需求,不同处理器的原生事件集合往往在功能上会有交集(例如那些和存储层次访问、Cache 一致性协议、周期和指令计数、功能单元和流水线状态等方面相关的事件),但是其对应的原生事件名称却未必相同。为了便于事件甄别,PAPI 将这些在不同处理器中存在功能共性的原生事件抽象成了 PAPI 接口专用的预制事件(Preset Event)并统一命名,所以具有一定的可移植性。

1、支持的性能计数器事件:

PAPI 支持一百多个事件。其标准事件分为 4 类:存储层次访问事件;周期与指令计数;功能部件与流水线状态事件; Cache 一致性事件,与 SMP 系统的 cache 一致性协议相关。

PAPI 包含一个工具程序papi_avail,,可以检测用户平台具有哪些事件,如:

此外还有papi_mem_info和papi_cost等命令,用来查看TLB,Cache信息和 查看papi开销等。

2、PAPI提供了两个向底层硬件的接口:

高层接口:比较简单,用于完成基本的计数测量(提供启动、停止和读取特定事件的能力)

PAPI 高层接口提供了一些访问硬件性能计数器所需的基本功能,例如配置计数器、启动计数、停止计数、读取计数器的数值等。高层接口只能利用 PAPI 预制事件,而不能够通过配置计数器去监测超出预制事件覆盖范围以外的处理器原生事件。不过,PAPI 高层接口能够直接返回在程序测评中最经常使用的一些性能指标,例如每个周期执行完成的指令数、每秒执行完成的浮点指令 / 浮点操作数、程序的运行时间等;另外,高层接口还能获取一些系统信息,例如处理器能够支持的硬件性能计数器的个数等。

底层接口:管理用户定义的事件组(称为 EventSet)中的事件,完全可编程,线程安全,为工具开发人员和高级用户提供方便。

高层接口获得的数据很多是未经过加工的原始数据,从中不能直接看出应用程序的存储层次与流水线利用情况的好坏。不同于高层接口只能使用 PAPI 预制事件,PAPI 底层接口能够直接使用原生事件对程序运行时的处理器硬件行为进行监测。用户可以将一个或多个原生事件组成一个事件组(Event Set),然后通过设置硬件性能计数器对事件组中所有的原生事件同时进行监测,进而根据监测结果分析程序的性能问题,例如通过同时采集每秒执行完成的浮点 指令数和 L1 Cache 失次数就有助于分析是否是因为 L1 Cache 的命中率不高导致了程序浮点性能的下降。需要注意的是,事件组中的原生事件个数不能够超过处理器所能支持的硬件性能计数器个数。

list . 常用的 PAPI 底层接口(C语言)

PAPI_library_init

初始化 PAPI 接口库

PAPI_create_eventset

创建事件组

PAPI_add_event / PAPI_add_events

向事件组中添加原生事件或者 PAPI 预制事件

PAPI_remove_event  PAPI_remove_events

从事件组中删除事件

PAPI_start

启动计数器对事件组的计数

PAPI_read

读取计数器数值

PAPI_stop

停止计数器计数并读取当前的计数器数值

PAPI_cleanup_eventset

清除事件组中的事件

PAPI_destroy_eventset

销毁事件组

PAPI_shutdown

终止使用 PAPI 并释放所有相关资源

//具体使用见后面实例2

PAPI是一组可以在多个处理器平台上对硬件性能计数器进行访问的本地接口,所以对于不同的处理器,安装方法也不同,部分AMD的CPU和INTEL的奔腾系列,至强系列都需要打补丁。补丁使用perfctr-2.6.x,对内核打补丁,重新编译的步骤比较繁琐,安装步骤在PAPI压缩包的Install.txt文件里有说明。

下面是对于一般的处理器(INTEL的i系列等)的安装步骤。

二、PAPI安装方法

在Ubuntu14.10上安装:

1、到PAPI官网下载PAPI 5.4.1压缩包。http://icl.cs.utk.edu/papi/software/index.html

2、将压缩包拷贝至/usr/local/下并解压。

3、测试PAPI

进入src目录并依次执行以下指令。

% ./configure

% make

% make test

如果出现PASSED则是通过测试,可以安装。

% make fulltest (相当于./run_tests.sh,简单测试,可忽略)

% ./run_tests.sh -v(详细测试)

如果提示没有权限就使用chmod命令更改权限即可。

这个过程比较缓慢,下面是部分过程截图。

4、安装PAPI

a) To install PAPI libraries and header files from the build tree:

% make install

b) To install PAPI manual pages from the build tree:

% make install-man

c) To install PAPI test programs from the build tree:

% make install-tests

d) To install all of the above in one step from the build tree:

% make install-all

e) To create a binary kit, papi-<arch>.tgz:

% make dist

papi默认是安装在 /usr/local 下的,
papi可执行命令安装在bin下

papi的头文件放在include下

papi的库文件放在lib下,包括静态库libpapi.a,动态库libpapi.so.5.4.1.0

还有share、man目录下也安装了一些东西

5、由于papi的相关库安装在 /usr/local/lib 下,而我们编译程序链接动态或者静态库时,默认不会再 /usr/local/lib 下查找相关库的,所以为了在编译程序时可以自动链接/usr/local/lib下的papi相关库(例如: gcc ** -lpapi),我们做如下操作:

将 /usr/local/lib  加入文件 /etc/ld.so.conf 的最后一行,然后执行 ldconfig 命令,在编译时需要加入编译选项 -lpapi,使得程序可以动态链接到相应的函数实现。

6、编写一个C程序,调用 papi 相关函数,使用命令 gcc *.c -lpapi 命令编译,查看是否能够正常使用 PAPI .

三、使用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();

四、实例测试

实例一

http://icl.cs.utk.edu/projects/papi/wiki/PAPITopics:Getting_Started  官网的例子

我的电脑输出的结果为:

实例二

 1 #include "papi.h"
 2
 3 #include <stdlib.h>
 4
 5 #include <stdio.h>
 6
 7 int main() {
 8
 9 int EventSet;
10
11 int i, sum;
12
13 long_long values[2], values1[2], values2[2];
14
15 if (PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT)
16
17 exit(-1);
18
19 EventSet = PAPI_NULL;
20
21 if (PAPI_create_eventset(&EventSet) != PAPI_OK)
22
23 exit(-1);
24
25 if (PAPI_add_event(EventSet, PAPI_TOT_INS) != PAPI_OK)
26
27 exit(-1);
28
29 if (PAPI_add_event(EventSet, PAPI_L1_DCM) != PAPI_OK)
30
31 exit(-1);
32
33 if (PAPI_start(EventSet) != PAPI_OK)
34
35 exit(-1);
36
37 if (PAPI_read(EventSet, values1) != PAPI_OK)
38
39 exit(-1);
40
41 for (i=0;i<10000;i++)
42
43 sum+=i;
44
45 if (PAPI_stop(EventSet, values2) != PAPI_OK)
46
47 exit(-1);
48
49 if (PAPI_cleanup_eventset(EventSet) != PAPI_OK)
50
51 exit(-1);
52
53 if (PAPI_destroy_eventset(&EventSet) != PAPI_OK)
54
55 exit(-1);
56
57 PAPI_shutdown();
58
59 /* Get value */
60
61 values[0]=values2[0]-values1[0];
62
63 values[1]=values2[1]-values1[1];
64
65 printf("TOT_INS:%lld\nL1_DCM: %lld\n",values[0], values[1]);
66
67 return 0;
68
69 }

我的电脑输出的结果为:

TOT_INS:50919

L1_DCM:14

实例三

 1 #include "papi.h"
 2
 3 #include <stdlib.h>
 4
 5 #include <stdio.h>
 6
 7 int main() {
 8
 9     int EventSet;
10
11     int i, sum;
12
13 long_long values[1], values1[1], values2[1];
14
15     /* Initialize the PAPI library */
16
17     if (PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT)
18
19                 exit(-1);
20
21       // exit(-1);
22
23     /* Create an EventSet */
24
25     EventSet = PAPI_NULL;
26
27     if (PAPI_create_eventset(&EventSet) != PAPI_OK)
28
29         exit(-1);
30
31     /* Add an event about Total Instructions Executed (PAPI_TOT_INS) to EventSet */
32
33     if (PAPI_add_event(EventSet, PAPI_TOT_INS) != PAPI_OK)
34
35         exit(-1);
36
37     /* Start counting events */
38
39     if (PAPI_start(EventSet) != PAPI_OK)
40
41         exit(-1);
42
43     /* Read counters before workload running*/
44
45     if (PAPI_read(EventSet, values1) != PAPI_OK)
46
47         exit(-1);
48
49     /* Do some computation here */
50
51         for (i=0;i<10000;i++)
52
53                 sum+=i;
54
55     /* Stop counting events */
56
57     /* Stop counting events */
58
59     if (PAPI_stop(EventSet, values2) != PAPI_OK)
60
61         exit(-1);
62
63     /* Clean up EventSet */
64
65     if (PAPI_cleanup_eventset(EventSet) != PAPI_OK)
66
67         exit(-1);
68
69     /* Destroy the EventSet */
70
71     if (PAPI_destroy_eventset(&EventSet) != PAPI_OK)
72
73         exit(-1);
74
75     /* Shutdown PAPI */
76
77     PAPI_shutdown();
78
79     /* Get value */
80
81 // values[0] = values2[0] – values1[0];
82
83         values[0]=values2[0]-values1[0];
84
85         printf("%lld\n",values[0]);
86
87         return 0;
88
89 }

我的电脑输出的结果为50891

实例四

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

#include<stdio.h>
int a[1000][1000];
int c[1000][1000];
int main()
{
int EventSet = PAPI_NULL;
int retval;
long_long values[1];
/* Initialize the PAPI library */
retval = PAPI_library_init(PAPI_VER_CURRENT);
if (retval != PAPI_VER_CURRENT) {
fprintf(stderr, "PAPI library init error!\n");
exit(1);
}
/* Create an EventSet */
if (PAPI_create_eventset(&EventSet) != PAPI_OK)
{
printf("create error\n");
exit(1);
}
/* Add Total Instructions Executed to our EventSet */
if (PAPI_add_event(EventSet, PAPI_L1_DCM) != PAPI_OK)
{
printf("add error\n");
exit(1);
}
if (PAPI_start(EventSet) != PAPI_OK)
{
printf("start error\n");
exit(1);
}
if (PAPI_read(EventSet, values) != PAPI_OK)
{
printf("read error\n");
exit(1);
}

int m,n;
for(m=0;m<1000;m++)
{
for(n=0;n<1000;n++)
{
a[n][m]=a[n][m]+m+n;
}
}
/* Do some computation here */
if (PAPI_read(EventSet, values) != PAPI_OK)
{
printf("read error\n");
exit(1);
}
long_long b=values[0];
if(PAPI_reset(EventSet)!=PAPI_OK)
{
printf("reset error\n");
exit(1);
}
for(m=0;m<1000;m++)
{
for(n=0;n<1000;n++)
{
c[m][n]=c[m][n]+m+n;
}
}
/* Do some computation here */
if (PAPI_stop(EventSet, values) != PAPI_OK)
{
printf("stop error\n");
exit(1);
}

if (PAPI_remove_event(EventSet, PAPI_L1_DCM) != PAPI_OK)
{
printf("stop error\n");
exit(1);
}

if (PAPI_destroy_eventset(&EventSet) != PAPI_OK)
{
printf("stop error\n");
exit(1);
}

PAPI_shutdown();
printf("%lld\n",b);
printf("%lld",values[0]);
getchar();
return 0;
}

我的电脑输出的结果为:

1364841

34786

最后推荐 http://www.ibm.com/developerworks/cn/java/j-lo-papi/  这篇文章写得很好。

时间: 2024-10-28 15:24:41

PAPI性能测试工具的安装、使用及实例的相关文章

性能测试工具--SIEGE安装及使用简介

官方网站http://www.joedog.org/ 概述 Siege是一个多线程http负载测试和基准测试工具.它有3种操作模式: 1) Regression (when invoked by bombardment)Siege从配置文件中读取URLs,按递归方式,逐个发送请求 2) Internet simulation (Siege从配置文件中读取URLs,随机选取URL发送请求) 3) Brute force (在命令行上写上一个单独的URL,发送请求) 安装 我这里使用的是最新版的.$

Mysql多线程性能测试工具sysbench 安装、使用和测试

From:http://www.cnblogs.com/zhoujinyi/archive/2013/04/19/3029134.html 摘要:      sysbench是一个开源的.模块化的.跨平台的多线程性能测试工具,可以用来进行CPU.内存.磁盘I/O.线程.数据库的性能测试.目前支持的数据库有MySQL.Oracle和PostgreSQL.当前功能允许测试的系统参数有: file I/O performance (文件I / O性能) scheduler performance (调

云存储性能测试工具--COSBench安装

COSBench安装 Cosbench是Intel的开源云存储性能测试软件,COSBench目前已经广泛使用与云存储测试,并作为云存储的基准测试工具使用 1 环境 1.1 操作系统 COSBench可在windows和linux两种系统中运行,而为了更好的发挥硬件和系统的能力,建议在使用COSBench进行测试时,选择linux系统,目前我使用的环境是:ubuntu 12.04系统版本: 1.2 运行环境 JRE 1.7+ CURL 2 安装 2.1 支持环境安装 2.1.1 JRE JRE安装

PHP性能测试工具xhprof安装与使用

原文链接:http://www.orlion.ga/711/ 一.安装 wget https://pecl.php.net/get/xhprof-0.9.4.tgz tar zxf xhprof-0.9.4.tgz cd xhprof-0.9.4.tgz/extension /usr/local/php/bin/phpize ./configure --with-php-config=/usr/local/php/bin/php-config make make install 然后修改php.

性能测试工具netperf安装使用

netperf工具使用 一.安装 1,下载 liunx下载地址:ftp://ftp.netperf.org/netperf/ windows版下载地址:ftp://ftp.netperf.org/netperf/misc/ 这里我下载版本:netperf-2.6.0.tar.gz 2,安装 [[email protected] home]# tar -zxvf netperf-2.6.0.tar.gz [[email protected] home]# cd netperf-2.6.0/ [[e

linux网络性能测试工具ipref安装与使用

一.iperf工具安装 源码包下载地址:https://iperf.fr/iperf-download.php#archlinux 选择对应系统的版本就是解压安装了 完成 测试发现有问题 问题原因:Linux系统中找不到libiperf.so.0 库文件,导致执行iperf3 –s时提示缺少相关lib库解决方法:通过find /usr/local/lib/ |grep iperf查找其他服务器上是否存在该lib库文件,查询到后拷贝libiperf.so.0库文件到此台服务器/usr/local/

性能测试工具之安装webbench

Webbench安装 1)安装环境:CentOS release 6.4 附录:查看系统信息 2)安装步骤:wget http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.gz tar zxvf webbench-1.5.tar.gz cd webbench-1.5 make && make install 附录:wget 查看wget版本确认是否安装 如没有安装需要下载安装 3)验证安装成功 问题跟踪:安装过程中如出现未找

Linux 性能测试工具Lmbench详解

Linux 性能测试工具Lmbench详解 2010-06-04 16:07 佚名 评测中心 字号:T | T Lmbench 是一套简易可移植的,符合ANSI/C 标准为UNIX/POSIX 而制定的微型测评工具.一般来说,它衡量两个关键特征:反应时间和带宽.Lmbench 旨在使系统开发者深入了解关键操作的基础成本. AD:2014WOT全球软件技术峰会北京站 课程视频发布 Linux 性能测试工具Lmbench 是一套简易可移植的,符合ANSI/C 标准为UNIX/POSIX 而制定的微型

Web性能测试工具:Siege安装&amp;使用简介

在Web性能测试工具中,siege是比较热门和常见的,它有安装简单,使用简单,测试报告详细的特点. 并且可以在文本中预定义一系列待测试url模拟,并可设定一定并发量下持续指定时间or测试进行测试. 比较适合确定真实环境下的系统性能基准. 1.下载安装包 略过 2.解压安装包 略过 3.编译 # 查看安装选项 ./configure --help # 设定安装选项 ./configure --prefix=/你的/安装/目录 # 编译 make # 安装 make install 4.参数详解 -