在ARM中有与rdtsc等价的指令吗?

Is there an equivalent instruction to rdtsc in ARM?

本文关键字:指令 rdtsc ARM      更新时间:2023-10-16

对于我的项目,我必须使用内联汇编指令,如rdtsc来计算一些C/c++指令的执行时间。

下面的代码似乎可以在Intel处理器上工作,但不能在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处理器上工作?

您应该读取协处理器p15(不是实际的协处理器,只是CPU函数的入口点)的PMCCNTR寄存器以获得周期计数。请注意,只有当

  1. 允许非特权PMCCNTR读取:

    PMUSERENR寄存器0位必须设置为1(官方文档)

  2. PMCCNTR实际上在计算周期:

    PMCNTENSET寄存器的第31位必须设置为1(官方文档)

这是一个真实世界的例子。

对于Arm64,系统寄存器CNTVCT_EL0可用于从中检索计数器用户空间。

// SPDX-License-Identifier: GPL-2.0
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;
}