使用硬件计数器测量 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-A9 上的缓存行为吗?

如何测量 ARM Cortex-A53 处理器中的程序执行时间?

1.ARM嵌入式体系结构与接口技术(Cortex-A8版)

ARM Cortex-A7 中的事件计数器

在 ARM Cortex-A8 上启用 MMU 时出现问题。 CPU是S5PV210

ARM-V7和ARM-V8架构的硬件