ARM Cortex-A8处理器中的程序执行时间

时间:2013-01-04 13:53:25

标签: arm cortex-a8 time-measurement performancecounter

我正在使用ARM Cortex-A8并尝试通过汇编代码从CCNT时间计数器读取值。我正在关注这篇文章How to measure program execution time in ARM Cortex-A8 processor?。根据它,在我可以从定时器读取值之前,我必须启用计数器,启用64位分频器并清除溢出。通过在适当的寄存器内写入来执行这些操作(例如,PMCR(性能监控寄存器))。所以,我在循环中打印计数器值以跟踪溢出的发生方式,并且我有这种行为:

1           (starts to incrementing after it was reset to zero)
4650
4858
4943
5023
...
...        (incrementing...)
...
4293939054
4293939128       (overflow happens)
1602570          
1602703
1602788
...
...
4293522911
4293522987
4293523062
4293523137
1186243
1186367
1186453
1186536
1186612
1186686
...
4293536300
4293536377
4293536456
4293536533
4293536612
1199090
1199209
1199295
1199373
1199453
1199530
….
and so forth.

因此,我有一系列问题:

a)Linux内核使用了哪些或上述寄存器? (进一步内核版本的信息有多可靠)。改变他们的价值观有多安全?

b)CCNT频率的准确值是多少以及如何得到它?不幸的是,我找不到处理器规范中的值。然而,dmesg说的是

[ 0.000000] OMAP clocksource: GPTIMER2 at 24000000 Hz
[ 0.000000] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms
[ 0.132855] Switching to clocksource gp timer

但是,根据clock_gettime手动识别它,可以得到7 MHz。那么,为什么不是预期的24 MHz?

c)根据我的第一个输出,为什么在溢出后它开始不是零,而是从大约1密耳?

d)为什么没有64分频器我得到错误的结果?价值开始以这种方式跳跃:

...
134110099
134114934
134119656
302352300
302361825
302367135
…
2885588930
2885593776
2885598630
3053958670
3053966752
3053972232
…
261130096
261134909
429343853
429351487
429356735

我很感激任何帮助。感谢

1 个答案:

答案 0 :(得分:4)

a)PMU regs可以由Linux内核的perf子系统使用(通过perf用户空间工具访问)。

b)CCNT频率是Cortex-A9 CPU周期计数器,如果启用分频器,则为cycle / 64。因此,带分频器的7MHz将是大约450 MHz的平均CPU时钟。这与24 MHz系统时钟分开。

c)也许你的过程已经安排好了。这是整个CPU的低级循环计数器,而不仅仅是您的过程。它将在内核或其他进程中继续运行。另一方面,如果您的进程迁移到另一个CPU,您将访问该CPU的循环计数器(甚至可能没有相同的分隔符设置)。如果你想要一致的计数,你应该将你的过程固定到一个CPU。

d)对(c)的类似答案,您可能会看到流程调度和迁移的影响。