2013-01-04 70 views
2

我正在使用ARM Cortex-A8,并试图通过汇编代码从CCNT时间计数器读取值。我正在关注这个帖子How to measure program execution time in ARM Cortex-A8 processor?。按照它,在我可以读取定时器的值之前,我必须启用计数器,启用64位分频器并清除溢出。这些操作通过在适当的寄存器(例如,PMCR(Performance Monitro控制寄存器))内写入来执行。所以,我打印的计数器值在循环中保持跟踪溢出是如何发生的,我有这种行为:ARM Cortex-A8处理器中的程序执行时间

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兆赫。那么,为什么它不像预期的那样是24 MHz?

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

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

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

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

回答

4

a)PMU寄存器可以被Linux内核的perf子系统使用(通过perf用户空间工具访问)。 b)CCNT频率是Cortex-A9 CPU周期计数器,如果启用分频器,则周期数/ 64。因此,使用分频器的7MHz将是大约450 MHz的平均CPU时钟。这与24 MHz系统时钟是分开的。 c)可能你的过程被排除了。这是整个CPU的低级循环计数器,而不仅仅是您的进程。它将在内核或其他进程中保持运行。另一方面,如果你的进程迁移到另一个CPU,你将访问该CPU的循环计数器(甚至可能没有相同的分频器设置)。如果你想要一致的计数,你应该把你的进程固定在一个CPU上。 d)与(c)类似的答案,您可能会看到进程调度和迁移的影响。

+1

感谢您的快速回复。关于b) - 我的问题是为什么我得到7 MHz(450 MHz)?我预计CCNT是那个系统时钟,我有它的24 MHz的频率值?我的目标是避免系统调用并访问内核的优先时钟,我认为这是CCNT。如果没有,我怎样才能访问系统时钟? – Irina

+0

不,CCNT由CPU周期驱动(可能除以64)。 CPU时钟频率可能因DVFS(动态电压/频率缩放)而异。如果您想读取以恒定频率运行的定时器,则需要访问全局定时器,而不是CCNT。 –