使用硬件计数器测量ARM Cortex-A8上的执行时间

我正在使用Exynos 3110处理器(1 GHz单核ARM Cortex-A8,例如在Nexus S中使用),并尝试测量特定function的执行时间。 我在Nexus S上运行了Android 4.0.3。我尝试了这个方法

[1] 如何在ARM Cortex-A8处理器中测量程序执行时间?

我加载了内核模块以允许在用户模式下读取寄存器值。 我正在使用以下程序来测试计数器:

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秒的hibernate,但计数器值在~200e6的范围内,而不是预期的1e9。 我在这里缺少什么特定处理器? 计数器的时钟频率是否与处理器的时钟速率不同?

看看这个教授的页面: http : //users.ece.utexas.edu/~valvano/arm/他有多个完整的示例程序,与时间/定期计时器/测量执行时间有关,它们是为基于ARM Cortex-M3的微控制器。 我希望这与你的工作没有太大的不同。 我想你会对Performance.c感兴趣

您是否确定在Android中使用调控器进行性能管理的方式与标准Linux相同? 您使用的是自定义Android图像还是制造商提供的图像? 我认为制造商提供的图像中存在较低级别的策略(与睡眠或调制解调器活动等有关)。 也可以是睡眠代码直接缩放电压和频率。 禁用整个CPUFreq而不仅仅是策略(或调控器)可能是值得的。