时钟周期计数变化 Cortex A53 AArch64

Posted

技术标签:

【中文标题】时钟周期计数变化 Cortex A53 AArch64【英文标题】:Clock Cycles Count Variation Cortex A53 AArch64 【发布时间】:2016-05-21 08:36:21 【问题描述】:

我尝试使用以下函数计算我在 ARM Cortex-A53 上的函数的 cpu 时钟周期:

#include <sys/time.h>
    readticks(unsigned int *result, int enabled)
    
      struct timeval t;
      unsigned int cc;
      unsigned int val;
      if (!enabled) 
               // program the performance-counter control-register:
             asm volatile("msr pmcr_el0, %0" : : "r" (17));
             //enable all counters
             asm volatile("msr PMCNTENSET_EL0, %0" : : "r" (0x8000000f));
            //clear the overflow 
            asm volatile("msr PMOVSCLR_EL0, %0" : : "r" (0x8000000f));
             enabled = 1;
      
      //read the coutner value
      asm volatile("mrs %0, PMCCNTR_EL0" : "=r" (cc));
      gettimeofday(&t,(struct timezone *) 0);
      result[0] = cc;
      result[1] = t.tv_usec;
      result[2] = t.tv_sec;
    

这是我的用户空间应用程序:

#include <stio.h>
#include <inttypes.h>
#include <time.h>

int main()
unsigned int init[3] = 0;
unsigned int start[3] = 0;
unsigned int end[3] = 0;
unsigned int overhead = 0;

readticks(init, 0);
readticks(start, 1);
readticks(end, 1);

overhead = end[0] - start[0];
readticks(init, 0);
readticks(start, 1);
foo(); //This is my function 
readticks(end, 1);

end[0] = end[0] - start[0] - overhead;
printf("clock cycles= %d\n", end[0]);
return 0;


当我多次运行我的代码时,我得到了不同的时钟周期,它们的变化相对较大(几乎 5000)。我的代码应该运行大约 4000 个时钟周期,但我有 4500 - 9500 个时钟周期。有什么办法可以让我更准确地计算时钟周期吗?

【问题讨论】:

除非你在没有操作系统或其他任何东西的裸机上运行它,否则中断之类的东西会占用周期。即使在裸机上,您的程序或环境中的细微差异也可能导致不同的缓存行为。 编译器可能会将您的汇编代码与其他代码混合在一起!对属于一起的代码使用 single asm 语句! enabled = 1; 没用,因为变量不再使用。你如何确保你的进程不被抢占? 您应该运行您希望为数千甚至数百万个周期计时的代码并取平均值。在某些情况下,计时测量的粒度可能很差。 如果你在 Linux 下使用愚蠢的 PMUSERENR_EL0 hack 从用户空间访问 PMU,你最多只能测量“一些东西”的执行——包括但不限于你的代码——和当您读取与您开始使用的循环计数器不同的循环计数器时,在最坏的情况下测量绝对的废话。 正确地管理 PMU 的代码已经在内核中:说真的,如果你想实际分析某些东西,请使用 perf。 @Notlikethat 我还没有自己编写 readticks 代码。似乎这种方法是获取 C 函数的近似时钟周期的常用方法。但是,我已经在我的问题中提到,显然这种方法不够准确,我正在寻找另一种方法。因此,如果您让我知道除了裸机还有哪些其他选择,我们将不胜感激! 【参考方案1】:

使用下面的宏

    #define mfcp(rn)    (u32 rval = 0U; \
             __asm__ __volatile__(\
               "mrc " rn "\n"\
               : "=r" (rval)\
             );\
             rval;\
             )
#endif

使用计数器寄存器调用 mfcp

uint64_t t1,t2;
t1 = mfcp(CNTPCT_EL0);
// your code
t2 = mfcp(CNTPCT_EL0);

【讨论】:

以上是关于时钟周期计数变化 Cortex A53 AArch64的主要内容,如果未能解决你的问题,请参考以下文章

迅为八核cortex a53开发板android/linux/Ubuntu系统

ARM Cortex A53上的NEON SIMD dotproduct速度不快

NEON 汇编代码在 Cortex-A72 与 Cortex-A53 上需要更多周期

ARM Cortex M4(或M3)上的周期计数器?

Cortex-m0之DualTimers定时器

STM32中,systick具体延时时间怎么计算的?