全局和对象变量之间的速度差异

时间:2010-09-23 06:24:30

标签: c++ assembly x86

访问全局变量或对象变量是否更快?

在C ++中,我指的是

之间的区别
::foo

this->foo

在x86汇编程序中,这基本上转换为

mov eax, offset foo

VS

mov eax, dword ptr[edx+foo]

两种情况下的所有数据都应该在缓存中。

(我知道差异,如果有的话会很小,而且通常应该选择哪一个使代码变得更简单;但在这种情况下,实际上没有其他区别,并且有问题的代码可能被称为5亿次在一个时间限制下,所以我不妨用更快的速度去。)

5 个答案:

答案 0 :(得分:8)

你需要测试和计时。

但是,要知道您在自己的应用中做出了其他决定,这些决定会比具有更强的性能影响几个数量级

对于人眼来说,Global的访问速度更快,但是编译器决定放在哪里,以及处理器决定如何缓存事物将最终决定哪个更快。

测试并计时。如果你在一个非常重要的应用程序中获得了数百万次运行中的有意义的差异,我会感到震惊。

答案 1 :(得分:4)

请不要对速度进行优化。

两者之间存在重要的语义差异,它带来代码的价值,以及最具逻辑意义的地方的数据,将比节省运行时性能节省更多时间。

几十亿次迭代并不是真的那么多。我的计算机中的CPU以2.2Ghz的速度运行。如果它在高速缓存中,则取消引用可能会花费额外的周期,因此1000亿次循环大约需要30秒的运行时间。我怀疑我会想念它。

答案 2 :(得分:3)

您是否考虑过第三种选择?

void bar()
{
   foo_t myFoo = ::foo; // or this->foo
   for(;;)
   {
       // do something with myFoo
   }
   ::foo = myFoo;
}

在这种情况下,编译器可能会将foo放入寄存器中,这肯定比缓存访问更快。

答案 3 :(得分:3)

与往常一样,选择使代码更简单的方法。

如果你使用全局,那么代码的读者必须想知道为什么,以及从哪里访问此变量。从中访问了多少个线程?如何同步来自不同线程的访问?

如果你创建的局部变量只在需要的地方可见,那么这些问题就会消失。

速度方面,唯一可能产生影响的是缓存局部性。如果经常访问该变量,它将在两种情况下都被缓存,但如果它位于其他最近使用的对象旁边,它们将能够共享相同的缓存行,从而在缓存中为其他数据留出更多空间

但如果代码值得优化,那么它也值得测量。

避免全局变量是一个简单,干净的选择。如果性能有问题,并且您的测量结果表明使用全局更快,则切换到全局。

但请记住,您也在改变程序的语义。如果您有多个线程调用该函数,如果您使用全局,那么您将获得竞争条件

答案 4 :(得分:1)

正如先前的评论员所说,衡量它。比较汇编程序指令对您没有帮助。预测计算机的行为cpu缓存几乎是不可能的,取决于其他所需的数据。此外,您的程序不一定是cpu绑定。

您可能希望使用 placement new 来确保持有foo的对象位于memore中的方便位置,以避免页面错误。