OProfile支持两种采样方式:基于事件的采样(Event Based)和基于时间的采样(Time Based)。基于事件的采样是OProfile只记录特定事件(比如L2缓存未命中)的发生次数,当达到用户设定的定值时Oprofile就记录一下〈采一个样)。这种方式需要CPU内部有性能计数器(Performace Counter)。基于时间的采样是OProfile借助OS时钟中断的机制,在每个时钟中断,OProfile都会记录一次(采一次样)。引入它的目的在于,提供对没有性能计数器的CPU的支持,其精度相对于基于事件的采样要低,因为要借助OS时钟中断的支持,对于禁用中断的代码,OProfile不能对其进行分析。OProfile在Linux上分两部分,一个是内核模块(oprofile.ko),另一个是用户空间的守护进程( oprofiled)。前者负责访问性能计数器或者注册基于时间采样的函数,并将采样值置于内核的缓冲区内。后者在后台运行,负责从内核空间收集数据,写入文件。其运行步骤如下:1)初始化opcontrol--init 2)配置opcontrol--setup--event=... 3)启动opcontrol--start 4)运行待分析的程序xxx 5)取出数据 6)分析结果opreport-1.x
用GNU gprof可以打印出程序运行中各个函数消耗的时间,以帮助程序员找出众多函数中耗时最多的函数还可产生程序运行时的函数调用关系,包括调用次数,以帮助程序员分析程序的运行流程。GNU gprof的实现原理:在编译和链接程序的时候(使用-pg编译和链接选项),gcc在应用程序的每个函数中都加入名为mcount (_mcount或_mcount,依赖于编译器或 *** 作系统)的函数,也就是说应用程序里的每一个函数都会调用mcount,而mcount会在内存中保存一张函数调用图,并通过函数调用堆栈的形式查找子函数和父函数的地址。这张调用图也保存了所有与函数相关的调用时间、调用次数等的所有信息。
linux下的方法:(1)使用命令time:
[root@localhost-120 xgf]# time ./standard
counter = 1000000
real0m0.006s
user0m0.000s
sys 0m0.000s
time命令对秒(s)级别的很精确,而对毫秒级的误差比价大。我们可以通过sleep/usleep函数来进行测试。sleep(0.1)或者usleep(100)都是表示休眠100ms,而测试结果都是:
real0m0.002s
user0m0.000s
sys 0m0.000s
(2)通过difftime函数:
double difftime(time_t time1, time_t time0)计算time1和time0之间的秒数。测试程序如下:
#include <stdio.h>
#include <time.h>
#define MAX 1000
int do_work()
{
int counter = 0 /* the counter */
int i, j /* the loop variable */
/* accumulate the counter */
for(i = 0i <MAXi++)
for(j = 0j <MAXj++)
counter++
/* return the counter's value */
return counter
}
int main()
{
time_t start, end
int val
start = time(NULL)
do_work()
end = time(NULL)
printf("val = %f/n", difftime(end, start))
return 0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)