简介oprofile
oprofile 是 Linux 平台上的一个功能强大的性能分析工具, 支持两种采样(sampling)方式:基于事件的采样(event based)和基于时间的采样(time based)。
基于事件的采样是oprofile只记录特定事件(比如L2 cache miss)的发生次数,当达到用户设定的 定值时oprofile 就记录一下(采一个样)。这种方式需要CPU 内部有性能计数器(performace counter)。
基于时间的采样是oprofile 借助OS 时钟中断的机制,每个时钟中断 oprofile 都会记录一次(采一次样)。引入的目的在于,提供对没有性能计数器 CPU 的支持。其精度相对于基于事件的采样要低。因为要借助 OS 时钟中断的支持,对禁用中断的代码oprofile不能对其进行分析。
运行问题
交叉编译成功,并初步运行成功,不代表整个程序没有任何后顾之忧。
下一步开始分析软件性能
1. 优先选择事件采样,因为它性能好精度高。
2.opcontrol --init 插入oprofile.ko驱动 挂载oprofilefs
3.opcontrol --setup --event=CPU_CYCLES:1000::0:1 --session-dir=/opt/gtk/testop/ 设置使用CPU周期事件采样 并且把采样信息输出到/opt/gtk/testop/中
4.使用如下代码保存成multiply.c 编译 arm-linux-gcc -g multiply.c -o multiply.arm
int fast_multiply(x, y) /multiply.c
{
return x * y;
}
int slow_multiply(x, y)
{
int i, j, z;
for (i = 0, z = 0; i < x; i++)
z = z + y;
return z;
}
int main()
{
int i,j;
int x,y;
for (i = 0; i < 2000; i ++) {
for (j = 0; j < 30 ; j++) {
x = fast_multiply(i, j);
y = slow_multiply(i, j);
}
}
return 0;
}
5.执行如下命令
opcontrol --start && ./multiply.arm && opcontrol --dump && opcontrol --stop
启动采样 执行程序 转储采样信息 停止采样
6.执行如下命令
opannotate --source ./multiply.arm 进行采样信息分析
却怎么也分析不到数据
总是提示如下错误
error: no sample files found: profile specification too strict ?
查了一下oprofile的FAQ(http://oprofile.sourceforge.net/faq/) 综合我们现在的情况大致意思是说我们的参数没有配置正确
7.解决问题
为了验证我们的各个软件的版本 binutils oprofile kernel popt的版本是否正确我们在X86的机器上进行了编译运行的实验,使用如上的的软件源码和测试代码 使用方法,成功的打印出如下信息
说明我们的方法没有错误
8.深入分析
综上所属,总结出结论在x86 和 arm 上的区别在于体系结构的差别,计划分析内核模块oprofile.ko在采样上的方式。
9.分析x86上采样的方式
我pc机的内核版本是2.6.26
经过printk打印最终定位为
arch/x86/oprofile/op_model_ppro.c +119 的
static int ppro_check_ctrs(struct pt_regs * const regs,
struct op_msrs const * const msrs)
函数中调用函数oprofile_add_sample向oprofilefs文件系统进行信息转储供后面的分析器(eg. opannotate)使用的
因为在注释掉这句以后X86执行上述操作也不再有信息上传,分析得到的结果也是
error: no sample files found: profile specification too strict ? 这样的错误
10.分析arm上采样的工作方式
经过分析,arm上的工作方式大致是 先配置 performance monitor unit 的寄存器,然后注册中断,到了事件到来的时候
中断就会被触发然后中断处理函数会调用oprofile_add_sample向oprofilefs文件系统进行信息转储供后面的分析器
(eg. opannotate)使用
在arm11的中断注册处理函数里面却没有发现中断处理函数
static irqreturn_t arm11_pmu_interrupt(int irq, void *arg) 被调用,因为只有这个函数调用oprofile_add_sample才会被调用
没有数据样本被采样,所以没有结果输出,查中断注册的地方结果发现了如下代码
static int irqs[] = {
#ifdef CONFIG_ARCH_OMAP2
3,
#endif
};
ret = arm11_request_interrupts(irqs, ARRAY_SIZE(irqs));
int arm11_request_interrupts(int *irqs, int nr)
{
unsigned int i;
int ret = 0;
for(i = 0; i < nr; i++) {
ret = request_irq(irqs[i], arm11_pmu_interrupt, IRQF_DISABLED, "CP15 PMU", NULL);
if (ret != 0) {
printk(KERN_ERR "oprofile: unable to request IRQ%u for MPCORE-EM\n",
irqs[i]);
break;
}
}
if (i != nr)
while (i-- != 0)
free_irq(irqs[i], NULL);
return ret;
}
数组irqs里面使用了预编译,也就是说这个中断只支持特定的CPU而不是通用的arm11核。
我们的机器不是 OMAP2系列自然中断没有被注册。
结论: 我们的硬件无法支持事件采样,只能使用下面的基于时间的采样。