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



我使用的是Exynos 3110处理器(1 GHz单核ARM Cortex-A8,例如用于Nexus S),并尝试测量特定功能的执行时间。我有一个在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, 0tn": "=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, 0tn" :: "r"(value));  
    // enable all counters:  
    asm volatile ("MCR p15, 0, %0, c9, c12, 1tn" :: "r"(0x8000000f));  
    // clear overflows:
    asm volatile ("MCR p15, 0, %0, c9, c12, 3tn" :: "r"(0x8000000f));
}

int main(int argc, char **argv)
{
    int i = 0;
    unsigned int start = 0;
    unsigned int end = 0;
    printf("Hello Countern");
    init_perfcounters(1,0);
    for(i=0;i<10;i++)
    {
        start = get_cyclecount();
        sleep(1); // sleep one second
        end = get_cyclecount();
        printf("%u %u %un", start, end, end - start);
    }
    return 0;
}

根据[1],计数器随每个时钟周期递增。我将scaling_governor切换到用户空间,并将CPU频率设置为1GHz,以确保Android不会更改时钟频率。

如果我运行该程序,将执行1秒的睡眠,但计数器值在~200e6的范围内,而不是预期的1e9。我这里缺少什么特定于处理器的东西吗?计数器的时钟速率与处理器的时钟速率不同吗?

查看此教授的页面:http://users.ece.utexas.edu/~ valvano/arm/他有多个与时间/周期性定时器/测量执行时间有关的完整示例程序,这些程序是为基于ARM Cortex-M3的微控制器开发的。我希望这与你正在做的没有太大的不同。我想您会对性能感兴趣。c

您确定安卓系统中使用的调控器与标准Linux中使用的一样用于性能管理吗?你使用的是定制的安卓镜像还是制造商提供的镜像?我认为在制造商提供的图像中有较低级别的策略(与睡眠或调制解调器活动等相关)。也可能是睡眠代码直接缩放电压和频率。禁用整个CPUFreq可能是值得的,而不仅仅是禁用策略(或调控器)。

相关内容

  • 没有找到相关文章

最新更新