Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 全局变量和对象变量之间的速度差_C++_Assembly_X86 - Fatal编程技术网

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

C++ 全局变量和对象变量之间的速度差,c++,assembly,x86,C++,Assembly,X86,访问全局变量或对象变量是否更快 在C++中,我指的是之间的区别。 ::foo 及 在x86汇编程序中,这基本上转化为 mov eax, offset foo vs 这两种情况下的所有数据都应在缓存中 我知道两者之间的差别很小,人们通常应该选择使代码更简单的代码;但在这种情况下,实际上没有其他区别,并且在一个时间限制下,所讨论的代码可能会被调用5亿次,因此我还是选择稍快一点的代码为准。正如前面的评论员所说,测量它。比较汇编程序指令对你没有帮助。预测计算机cpu缓存的行为几乎是不可能的,这取决于

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

在C++中,我指的是

之间的区别。
::foo

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

mov eax, offset foo
vs

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


我知道两者之间的差别很小,人们通常应该选择使代码更简单的代码;但在这种情况下,实际上没有其他区别,并且在一个时间限制下,所讨论的代码可能会被调用5亿次,因此我还是选择稍快一点的代码为准。

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


您可能希望使用placement new来确保保存foo的对象位于内存中一个方便的位置,以避免出现页面错误。

您需要同时测试和计时

然而,要做到这一点,就要知道你已经在应用程序中做出了其他决定,这些决定将对性能产生比这更大的几个数量级的影响

对于人类来说,全局的访问速度更快,但是编译器决定把什么放在哪里,处理器决定如何缓存东西,最终将决定哪个更快


测试它并计时。如果一个非平凡的应用程序在数百万次的运行中出现了有意义的差异,我会感到震惊。

请不要为了速度而优化它

两者之间有一个重要的语义差异,它给代码带来的价值,以及数据在最合乎逻辑的地方,将为您节省更多的时间,而不是降低运行时性能


几十亿次迭代其实并不多。我电脑中的CPU以2.2Ghz的速度运行。如果它在缓存中,取消引用可能需要额外的周期,因此1000亿个循环大约需要30秒的运行时间。我怀疑我会错过它。

你考虑过第三种选择吗

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

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

与往常一样,使用使代码更简单的方法

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

如果你使一个局部变量只在需要的地方可见,那么这些问题就消失了

就速度而言,唯一可能起作用的是缓存位置。如果经常访问该变量,则在这两种情况下都会对其进行缓存,但如果该变量位于其他最近使用的对象旁边,则它们将能够共享同一缓存线,从而在缓存中为其他数据留出更多空间

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

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


但请记住,您也在更改程序的语义。如果您有多个线程调用该函数,那么如果您使用一个全局函数,您将得到一个竞争条件,在这之前它是安全的

那么测试和计时这两个变量如何?如果重要的话,值得计时。也就是说,成员变量可能更经常地与其他数据一起缓存在缓存中。在时间限制下?这是什么时间限制?每秒5亿次访问可能意味着它对性能很重要,但每小时5亿次将使它变得完全无关紧要。编译器在分配寄存器方面并没有那么糟糕。事实上,我不知道还有哪个编译器会尊重register关键字,因为他们都相信自己根本不需要提示。编译器更倾向于使用寄存器作为局部变量,而不是必须有地址的变量,例如,存在于可执行映像中的全局变量或显式取消引用的值,如->foo+1,因为如果代码值得优化,那么它也值得测量。请注意,某些低性能处理器可能会出现速度差异。更重要的是,具有小偏移量的相对负载可能比绝对负载小;我通常更喜欢在I-cache中占用更少空间的版本。而下一票是因为。?如果你不同意我的回答,你能告诉我为什么吗?我想知道它出了什么问题,毕竟我们都在这里学习:
mov eax, dword ptr[edx+foo]
void bar()
{
   foo_t myFoo = ::foo; // or this->foo
   for(;;)
   {
       // do something with myFoo
   }
   ::foo = myFoo;
}