在浏览开源代码(来自 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
从another question开始,我得出的结论是,是否实际需要完成或由编译器自动完成的答案可能依赖于编译器/设置。 < / p>
我的问题是,如果_foo
是static
班级成员会有什么不同吗?在手动优化中是否还有一点,或者访问静态类成员不比访问局部变量更“昂贵”?
P.S。 - 我是出于好奇而不是解决具体问题。
答案 0 :(得分:6)
访问属性意味着取消引用该对象,以便访问它。
由于属性在执行期间可能会发生变化(读取线程),因此每次访问该值时,编译器都会从内存中读取值。
使用局部变量将允许编译器使用寄存器作为值,因为它可以安全地假设该值不会从外部更改。这样,该值只能从内存中读取一次。
关于静态成员的问题,它是相同的,因为它也可以被另一个线程更改,例如。编译器还需要每次从内存中读取值。
答案 1 :(得分:4)
我认为局部变量更有可能参与某些优化,正是因为它是函数的 local :编译器可以使用这个事实,例如,如果它看到没有人修改 local 变量,然后编译器可以加载一次,并在每次迭代中使用它。
如果是成员数据,编译器可能需要更多工作才能得出结论,没有人修改成员。考虑一下多线程应用程序,并注意C ++ 11中的内存模型是多线程的,这意味着其他一些线程可能会修改该成员,因此编译器可能不会断定没有人修改它,因此它必须发出 load 成员的代码,用于每个使用它的表达式,可能在一次迭代中多次,以便使用成员的更新值。
答案 2 :(得分:0)
在此示例中,_foo将被复制到新的局部变量中。所以两种情况都一样。 Statis值与任何其他变量一样。它只是存储在专用于静态内存的不同内存段中。
答案 3 :(得分:-1)
读取静态类成员实际上就像读取全局变量一样。他们都有一个固定的地址。读取非静态的意味着首先读取this-pointer,向结果添加偏移量,然后读取该地址。换句话说,读取非静态的操作需要更多的步骤和内存访问。