我正在使用rdtsc和cpuid指令(使用易失性内联汇编指令)来测量程序的CPU周期。 rdtsc指令为Linux上的程序(带速度优化-o2 -fomit-frame-pointer)和Windows(使用MS Visual Studio 2008的速度优化选项C编译器(我认为它的VC 9.0))提供了真实的结果。
最近,我实现了一个新程序,它使用了大量的表查找和类似的东西。 但是,在Linux上使用gcc优化的程序的rdtsc测量总是导致错误的测量(非常少的CPU周期)比我预期的。 在Windows上运行时相同程序的rdtsc测量(使用上面提到的优化和编译器编译)是现实的,并且同意了预期。
我的问题是,有什么方法gcc优化移动volatile组件指令一些产生上述行为的地方?
我的定时器代码如下:
#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")
如果某个机构可以对此提出一些想法,我将非常感激。
谢谢,
为了防止内联rdtsc
函数在任何加载/存储/其他操作中移动,您应该将asm写为__asm__ __volatile__
并在clobber列表中包含"memory"
。 如果不执行后者,GCC将被阻止移除asm或将其移动到可能需要asm的结果(或更改输入)的任何指令,但它仍然可以针对不相关的操作移动它。 "memory"
破坏意味着GCC无法对内存内容做出任何假设(任何地址可能泄漏的变量)在asm中保持不变,因此移动它变得更加困难。 但是,GCC 仍然可以将asm移动到仅修改其地址从未被占用的局部变量的指令(因为它们不是"memory"
)。
哦,正如wildplasser在评论中所说,在你浪费大量时间之前检查asm输出 。
我不知道它是否正确,但我曾用过的代码是:
#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; }
我记得它在英特尔上比在AMD上“慢”。 因人而异。
需要了解更多c/c++开发分享使用rdtsc进行gcc优化的问题,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享使用rdtsc进行gcc优化的问题相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979758.html