使用硬件计数器测量 ARM Cortex-A8 上的执行时间
Posted
技术标签:
【中文标题】使用硬件计数器测量 ARM Cortex-A8 上的执行时间【英文标题】:Measure executing time on ARM Cortex-A8 using hardware counter 【发布时间】:2012-03-20 21:18:19 【问题描述】:我正在使用 Exynos 3110 处理器(1 GHz 单核 ARM Cortex-A8,例如用于 Nexus S)并尝试测量特定功能的执行时间。我在 Nexus S 上运行 android 4.0.3。我尝试了
中的方法[1]How to measure program execution time in ARM Cortex-A8 processor?
我加载了内核模块以允许在用户模式下读取寄存器值。我正在使用以下程序来测试计数器:
static inline unsigned int get_cyclecount (void)
unsigned int value;
// Read CCNT Register
asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
return value;
static inline void init_perfcounters (int do_reset, int enable_divider)
// in general enable all counters (including cycle counter)
int value = 1;
// peform reset:
if (do_reset)
value |= 2; // reset all counters to zero.
value |= 4; // reset cycle counter to zero.
if (enable_divider)
value |= 8; // enable "by 64" divider for CCNT.
value |= 16;
// program the performance-counter control-register:
asm volatile ("MCR p15, 0, %0, c9, c12, 0\t\n" :: "r"(value));
// enable all counters:
asm volatile ("MCR p15, 0, %0, c9, c12, 1\t\n" :: "r"(0x8000000f));
// clear overflows:
asm volatile ("MCR p15, 0, %0, c9, c12, 3\t\n" :: "r"(0x8000000f));
int main(int argc, char **argv)
int i = 0;
unsigned int start = 0;
unsigned int end = 0;
printf("Hello Counter\n");
init_perfcounters(1,0);
for(i=0;i<10;i++)
start = get_cyclecount();
sleep(1); // sleep one second
end = get_cyclecount();
printf("%u %u %u\n", start, end, end - start);
return 0;
根据 [1],计数器随着每个时钟周期递增。我将 scaling_governor 切换到用户空间并将 CPU 频率设置为 1GHz,以确保时钟频率不会被 Android 更改。
如果我运行程序,则会执行 1 秒的休眠,但计数器值在 ~200e6 的范围内,而不是预期的 1e9。我在这里缺少任何特定于处理器的东西吗?计数器的时钟频率是否与处理器的时钟频率不同?
【问题讨论】:
酷..你发布的代码完全是我两年前写的..只是想知道:你从哪里得到的? 嗨 Nils,这是你的代码,我引用了那个时候的主题 ;-) 你知道为什么我在计时器值中得到 5 的因子吗?谢谢 如果你做一秒钟的实际工作而不是睡觉,测量的时间会改变吗? 嗨尼尔斯,谢谢!事实上,睡眠似乎会影响计数器。对于秒范围内的执行时间,我现在得到了合理的结果。我现在使用三种方法测量了更长的程序执行时间:1) 手动 2) 使用计数器 3) 使用函数 gettimeofday()。对于 129 秒的程序运行时间,计数器值关闭了 36 秒。猜猜什么会影响计数器?我需要尽可能精确地记录函数调用,包括更长时期(5-10 分钟)的时间戳,我想知道最好的方法是什么。 尽管调速器发生了变化,但 Android 似乎仍在扩展频率。如果我运行计时测量并且手机上的工作负载非常低,则计数器和 gettimeofday() 之间的差异明显大于工作负载较高的情况......看起来我应该看看 Android 的电源管理部分:-) 【参考方案1】:查看这位教授的页面:http://users.ece.utexas.edu/~valvano/arm/ 他有多个与时间/周期定时器/测量执行时间有关的完整示例程序,它们是为基于 ARM Cortex-M3 的微控制器开发的。我希望这与您的工作没有太大不同。 我想你会对 Performance.c
感兴趣【讨论】:
【参考方案2】:您确定在 Android 中使用调控器进行性能管理的方式与在标准 Linux 中相同吗?您使用的是自定义 Android 图像还是制造商提供的图像?我会假设制造商提供的图像中有较低级别的策略(与睡眠或调制解调器活动等相关)。也可能是睡眠代码直接缩放电压和频率。禁用整个 CPUFreq 可能是值得的,而不仅仅是策略(或调控器)。
【讨论】:
以上是关于使用硬件计数器测量 ARM Cortex-A8 上的执行时间的主要内容,如果未能解决你的问题,请参考以下文章
如何测量 ARM Cortex-A53 处理器中的程序执行时间?