对于我的项目我必须使用内联汇编指令,例如 rdtsc 来计算某些C / C ++指令的执行时间。
以下代码似乎适用于英特尔,但不适用于ARM处理器:
{unsigned a, d;asm volatile("rdtsc" : "=a" (a), "=d" (d)); t0 = ((unsigned long)a) | (((unsigned long)d) << 32);}
//The C++ statement to measure its execution time
{unsigned a, d;asm volatile("rdtsc" : "=a" (a), "=d" (d)); t1 = ((unsigned long)a) | (((unsigned long)d) << 32);}
time = t1-t0;
我的问题是:
如何在ARM处理器上编写内联汇编代码(计算指令的执行耗用时间)?
答案 0 :(得分:8)
您应该阅读协处理器PMCCNTR
的{{1}}寄存器(不是实际的协处理器,只是CPU功能的入口点)来获取循环计数。请注意,只有在以下情况下才能使用非特权应用:
包含非特权p15
读取内容:
PMCCNTR
寄存器的第0位必须设置为1(official docs)
PMUSERENR
实际上是计算周期:
PMCCNTR
寄存器的第31位必须设置为1(official docs)
这是a real-world example它是如何完成的。
答案 1 :(得分:3)
对于 Arm64,系统寄存器 CNTVCT_EL0
可用于从
用户空间。
u64 rdtsc(void)
{
u64 val;
/*
* According to ARM DDI 0487F.c, from Armv8.0 to Armv8.5 inclusive, the
* system counter is at least 56 bits wide; from Armv8.6, the counter
* must be 64 bits wide. So the system counter could be less than 64
* bits wide and it is attributed with the flag 'cap_user_time_short'
* is true.
*/
asm volatile("mrs %0, cntvct_el0" : "=r" (val));
return val;
}
有关详细信息,请参阅此补丁 https://lore.kernel.org/patchwork/patch/1305380/。