Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
时钟周期计数变化皮质A53 AArch64_C_Arm_Clock_Cortex A - Fatal编程技术网

时钟周期计数变化皮质A53 AArch64

时钟周期计数变化皮质A53 AArch64,c,arm,clock,cortex-a,C,Arm,Clock,Cortex A,我尝试使用以下功能为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 perfo

我尝试使用以下功能为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;
    }
#包括
readticks(无符号整数*结果,整数已启用)
{
结构时间值t;
无符号整数cc;
无符号int-val;
如果(!已启用){
//对性能计数器控制寄存器进行编程:
asm挥发性(“msr pmcr_el0,%0):“r”(17));
//启用所有计数器
asm volatile(“msr PMCNTENSET_EL0,%0):“r”(0x8000000f));
//清除溢出物
asm volatile(“msr PMOVSCLR_EL0,%0”::“r”(0x800000F));
启用=1;
}
//读取coutner值
asm volatile(“mrs%0,PMCCNTR_EL0”:“=r”(cc));
gettimeofday(&t,(结构时区*)0);
结果[0]=cc;
结果[1]=t.tv_usec;
结果[2]=t.tv_秒;
}
这是我的用户空间应用程序:

#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;

}
#包括
#包括
#包括
int main(){
无符号int init[3]={0};
无符号整数起始[3]={0};
无符号整数结束[3]={0};
无符号整数开销=0;
readticks(init,0);
readticks(开始,1);
readticks(结束,1);
开销=结束[0]-开始[0];
readticks(init,0);
readticks(开始,1);
foo();//这是我的函数
readticks(结束,1);
结束[0]=结束[0]-开始[0]-开销;
printf(“时钟周期=%d\n”,结束[0]);
返回0;
}

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

使用以下宏

    #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);

使用以下宏

    #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);

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