首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于rdtsc的gcc优化问题

基于rdtsc的gcc优化问题
EN

Stack Overflow用户
提问于 2012-05-09 22:49:50
回答 2查看 2.3K关注 0票数 1

我使用rdtsc和cpuid指令(使用易失性内联汇编指令)来测量程序的CPU周期。rdtsc指令给出了我的程序在Linux (具有速度优化-o2 -fomit-frame-pointer)和Windows (使用速度优化选项C编译器for MS Visual Studio2008(我想是它的VC9.0))上的实际结果。

最近,我实现了一个新的程序,它使用了大量的表查找和类似的东西。然而,在Linux上对这个带有gcc优化的程序进行的rdtsc测量总是导致错误的测量(非常少的CPU周期),比我预期的要少。在Windows上运行同一程序(使用我上面提到的优化和编译器编译)的rdtsc测量结果是真实的,符合预期。

我的问题是,有没有办法把gcc优化的易失性汇编指令移到哪里去产生上述行为呢?

我的定时器代码如下:

代码语言:javascript
复制
#define TIMER_VARS                                                 \
  uint32 start_lo, start_hi;                                       \
  uint32 ticks_lo, ticks_hi

#define TIMER_START()                                              \
  __asm__ __volatile__                                             \
     ("rdtsc"                                                      \
     : "=a" (start_lo), "=d" (start_hi) /* a = eax, d = edx*/      \
     : /* no input parameters*/                                    \
     : "%ebx", "%ecx", "memory")

#define TIMER_STOP()                                               \
  __asm__ __volatile__                                             \
     ("rdtsc"                                                      \
     "\n        subl %2, %%eax"                                    \
     "\n        sbbl %3, %%edx"                                    \
     : "=&a" (ticks_lo), "=&d" (ticks_hi)                          \
     : "g" (start_lo), "g" (start_hi)                              \
     : "%ebx", "%ecx", "memory")

如果有人能对此提出一些建议,我将不胜感激。

谢谢,

EN

回答 2

Stack Overflow用户

发布于 2012-05-10 00:02:22

为了防止内联asm函数跨任何加载/存储/其他操作移动,您应该将rdtsc编写为__asm__ __volatile__,并将"memory"包含在clobber列表中。如果不执行后一种操作,将阻止GCC删除asm或在可能需要asm的结果(或更改输入)的任何指令之间移动它,但它仍然可以相对于不相关的操作移动它。"memory"拦截器意味着,对于内存内容(其地址可能被泄漏的任何变量)在整个asm中保持不变,GCC不能做出任何假设,因此移动它变得更加困难。然而,GCC可能仍然能够在指令之间移动asm,这些指令只修改地址从未被获取的局部变量(因为它们不是"memory")。

哦,正如wildplasser在评论中所说的那样,在你在这上面浪费很多时间之前,应该检查一下asm的输出

票数 3
EN

Stack Overflow用户

发布于 2012-05-11 01:09:40

我不知道它是否正确,但我曾经使用的代码是:

代码语言:javascript
复制
#define rdtscll(val) \
      __asm__ __volatile__("rdtsc" : "=A" (val))

typedef unsigned unsigned long long Ull;

static inline Ull myget_cycles (void)
{
Ull ret;

rdtscll(ret);
return ret; 
}

我记得在Intel上比在AMD上“慢”。YMMV.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10518547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档