在ARM中是否有与rdtsc等效的指令?

时间:2016-11-06 20:26:20

标签: c++ c assembly arm inline-assembly

对于我的项目我必须使用内联汇编指令,例如 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处理器上编写内联汇编代码(计算指令的执行耗用时间)?

2 个答案:

答案 0 :(得分:8)

您应该阅读协处理器PMCCNTR的{​​{1}}寄存器(不是实际的协处理器,只是CPU功能的入口点)来获取循环计数。请注意,只有在以下情况下才能使用非特权应用:

  1. 包含非特权p15读取内容:

    PMCCNTR寄存器的第0位必须设置为1(official docs

  2. PMUSERENR实际上是计算周期:

    PMCCNTR寄存器的第31位必须设置为1(official docs

  3. 这是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/