2

我正在使用 ARM Cortex-A8 并尝试通过汇编代码从 CCNT 时间计数器中​​读取值。我正在关注这篇文章如何测量 ARM Cortex-A8 处理器中的程序执行时间? . 根据它,在我可以从定时器读取值之前,我必须启用计数器,启用 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

我会很感激任何帮助。谢谢

4

1 回答 1

4

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

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

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

d) 与 (c) 类似的答案,您可能会看到进程调度和迁移的效果。

于 2013-01-04T15:46:14.873 回答