C++ 将静态类成员复制到局部变量以进行优化

C++ 将静态类成员复制到局部变量以进行优化,c++,optimization,C++,Optimization,在浏览开源代码(来自OpenCV)时,我在方法中遇到了以下类型的代码: // copy class member to local variable for optimization int foo = _foo; //where _foo is a class member for (...) //a heavy loop that makes use of foo 从那时起,我得出结论,这是否确实需要由编译器完成或由编译器自动完成的答案可能取决于编译器/设置。 我的问题是,如果\u fo

在浏览开源代码(来自OpenCV)时,我在方法中遇到了以下类型的代码:

// copy class member to local variable for optimization
int foo = _foo; //where _foo is a class member

for (...) //a heavy loop that makes use of foo
从那时起,我得出结论,这是否确实需要由编译器完成或由编译器自动完成的答案可能取决于编译器/设置。

我的问题是,如果
\u foo
静态的
类成员,会不会有什么不同?这种手动优化还会有意义吗,或者访问静态类成员不会比访问局部变量更“昂贵”吗


附言——我的请求是出于好奇,不是为了解决特定问题。

访问属性意味着为了访问它而取消引用对象

由于该属性在执行过程中可能会更改(读取线程),因此每次访问该值时,编译器都会从内存中读取该值

使用局部变量将允许编译器对值使用寄存器,因为它可以安全地假定值不会从外部更改。这样,该值从内存中只读取一次


关于关于静态成员的问题,它是相同的,例如,它也可以由另一个线程更改。编译器还需要每次从内存中读取值。

我认为局部变量更有可能参与某些优化,因为它是函数的局部变量:编译器可以使用这一事实,例如,如果它看到没有人修改局部变量,则编译器可能会加载它一次,并在每次迭代中使用它


对于成员数据,编译器可能需要做更多的工作才能得出没有人修改成员的结论。考虑多线程应用程序,注意C++11中的内存模型是多线程的,这意味着其他线程可能会修改成员,因此编译器可能不会得出没有人修改它的结论,因此它必须为使用它的每个表达式的load成员发出代码,可能在一次迭代中多次,为了使用成员的更新值。

在本例中,\u foo将被复制到新的局部变量中。所以这两种情况都是一样的。
Statis值与任何其他变量一样。它只是存储在专用于静态内存的不同内存段中。

读取静态类成员实际上就像读取全局变量一样。他们都有固定的地址。读取非静态指针意味着首先读取该指针,向结果添加偏移量,然后读取该地址。换句话说,读一个非静态的数据需要更多的步骤和内存访问。

做一个测试用例,测量和比较,和/或读取程序集。@ KerrekSB,我不相信自己在C++中写的正确的测试用例。我认为这不是真的。相反,事实正好相反:除非您(显式或隐式)跨越内存障碍,否则编译器可以假定该值没有更改。内存障碍不是隐式的。锁定互斥体意味着内存条。实际上,我肯定您的说法是错误的。当使用多个线程时,您必须假设它们也由不同的CPU执行。由于现代CPU至少有一级缓存,因此访问RAM不是直接的,而是默认通过缓存完成的。这意味着,如果线程A向地址X写入一个值,而线程B在没有进一步同步的情况下从同一地址读取一个值,那么它将不会获得先前写入的值。因为你无论如何都需要同步以使事情跨线程工作,所以你不必担心那些没有同步的事情。当然,永远不要担心同步。。。这当然是个好建议。你为什么不自己测试看看呢?我希望得到建设性的反馈,而不是简单的否决。