2016-11-06 238 views
7

对于我的项目我必须使用内联汇编指令(如rdtsc)来计算某些C/C++指令的执行时间。ARM中是否存在对rdtsc的等效指令?

下面的代码似乎对英特尔但不能在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

多核处理器上的'rdtsc'可能有问题。请参阅https://msdn.microsoft.com/en-us/library/ee417693(VS.85).aspx –

+0

单指令将具有基于缓存等可变计时。更好地循环数千次,它/他们并使用perf_events()通用功能,使其可以在所有支持的CPU上工作。 – BitBank

回答

6

您应该阅读协处理器p15(不是实际的协处理器,只是CPU功能的入口点)的PMCCNTR寄存器以获取周期数。请注意,它是提供给无特权的应用程序,仅当:

  1. 非特权PMCCNTR读取的alowed:

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

  2. PMCCNTR实际上是计数周期:

    PMCNTENSET位31必须设置为1(official docs

这是a real-world example它是如何完成的。

+0

@Curious请注意,以上答案适用于ARMv6及更高版本。较早的拱形版本可能有自己的获取这些数据的方法(特定于某个特定芯片 - 因此该信息可在芯片的数据表中找到),而一些基于ARM的芯片根本不提供这些数据。 –

+0

**我的ARM CPU是ARM7A **,但是通过使用编译器宏_ARM_ARCH_7A__确认,当我尝试使用指令asm volatile(“mrc p15,0,**%0 **,c9,c13,0” :“= r”(pmccntr));编译器给出错误信息:Error“no such instruction”asm volatile(“mrc p15,0,**%eax **,c9,c13,0”:“= r “(pmccntr)); – Curious

+0

**我生成环境= ** PLATFORM_VERSION_CODENAME = REL PLATFORM_VERSION = 4.3 TARGET_PRODUCT = full_manta TARGET_BUILD_VARIANT =主机 TARGET_BUILD_TYPE =释放 TARGET_BUILD_APPS = TARGET_ARCH =手臂 TARGET_ARCH_VARIANT = ARMv7的-A-氖 TARGET_CPU_VARIANT =皮质-A15 HOST_ARCH = 86 HOST_OS = Linux的 HOST_OS_EXTRA = Linux的3.16.0-70泛型-x86_64的与 - Ubuntu的14.04,值得信赖的 HOST_BUILD_TYPE =释放 BUILD_ID = JWR66V OUT_DIR =出 – Curious