ARM性能计数器vs linux clock_gettime

时间:2012-11-20 13:14:59

标签: linux arm performancecounter gettime time-measurement

我在开发板(ZC702)上使用Zynq芯片, 它具有667MHz的双皮质-A9 MPCore,并配有Linux内核3.3 我想比较一个程序的执行时间,所以首先使用 clock_gettime然后使用协处理器提供的计数器 ARM计数器每个处理器周期递增一次。 (基于此question of stackoverflowthis

我使用-O0标志编译程序(因为我不希望任何重新排序或优化)

我用性能计数器测量的时间是 583833498(周期)/ 666.666687 MHz = 875750.221 (微秒)

使用clock_gettime()(REALTIME或MONOTONIC或MONOTONIC_RAW) 测量的时间是: 731627.126 (微秒) 这是 150000 微秒..

有人能解释我为什么会这样吗? 为什么会有区别?处理器没有时钟缩放,怎么可能 通过clock_gettime测量的执行时间更少?我在下面有一个示例代码:


#define RUNS 50000000
#define BENCHMARK(val) \
__asm__  __volatile__("mov r4, %1\n\t" \
                 "mov r5, #0\n\t" \
                 "1:\n\t"\
                 "add r5,r5,r4\n\t"\
                 "mov r4 ,r4  \n\t" \
                 "mov r4 ,r4  \n\t" \
                 "mov r4 ,r4  \n\t" \
                 "mov r4 ,r4  \n\t" \
                 "mov r4 ,r4  \n\t" \
                 "mov r4 ,r4  \n\t" \
                 "mov r4 ,r4  \n\t" \
                 "mov r4 ,r4  \n\t" \
                 "mov r4 ,r4  \n\t" \
                 "mov r4 ,r4  \n\t" \
                 "sub r4,r4,#1\n\t" \
                 "cmp r4, #0\n\t" \
                 "bne 1b\n\t" \
                 "mov %0 ,r5  \n\t" \
                 :"=r" (val) \
                 : "r" (RUNS) \
                 : "r4","r5" \
        );
clock_gettime(CLOCK_MONOTONIC_RAW,&start);
__asm__ __volatile__ ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(start_cycles));
for(index=0;index<5;index++)
{
    BENCHMARK(i);
}
__asm__ __volatile__ ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(end_cycles));
clock_gettime(CLOCK_MONOTONIC_RAW,&stop);

2 个答案:

答案 0 :(得分:3)

我找到了解决方案。我将平台从Linux内核3.3.0升级到3.5,其值与性能计数器类似。显然,假设3.3.0中的时钟计数器的频率高于(大约400 MHz)而不是CPU频率的一半。可能是旧版本中的移植错误。

答案 1 :(得分:0)

POSIX时钟以一定的精度运行,您可以使用clock_getres获得。检查150,000us差异是否在误差范围之内或之外。

无论如何,它应该无关紧要,你应该多次重复你的基准,而不是5,而是1000或更多。然后,您可以获得单个基准测试运行的时间,如

((end + e1) - (start + e0)) / 1000

(end - start) / 1000 + (e1 - e0) / 1000

如果e1e0是误差项,它们受一个小常数的约束,那么您的最大测量误差将是abs (e1 - e0) / 1000,随着循环次数的增加,这个误差可以忽略不计