我经常看到编译器将本地函数变量放在寄存器中。我对此有疑问。
如果我大量使用某个类成员变量(整数/指针等),是否有意义,临时将其复制到局部变量,使用它,然后将结果复制到类成员?
例如(填写单向ptr列表):
struct MyClass{
struct ObjectHolder{
ObjectHolder* next_free;
};
ObjectHolder *next_free = nullptr;
void fill(){
ObjectHolder *copy_of_free = next_free ; // copy to register?
for (int i = 0; i < capacity; ++i) {
ObjectHolder &obj = array[i];
// build chain of pointers
obj.next_free = copy_of_free;
copy_of_free = &obj;
}
next_free = copy_of_free; // back to memory
}
}
答案 0 :(得分:4)
您在代码中描述的内容不仅仅是将成员变量复制到局部变量中以启用寄存器放置。从本质上讲,您的问题说明了两种方法之间的区别:
您的计划遵循方法#1。它比#2更强大,因为在执行计算时对象保持一致状态。
方法#1也可以为编译器提供更多优化代码的机会。然而,这是次要影响;你的对象在计算过程中保持一致更为重要。
答案 1 :(得分:0)
这些操作没有任何意义,因为编译器本身可以将数据成员的值放在寄存器中以优化代码。此外,如果您将数据成员放在局部变量中,它可以以这样的方式发生,这只会使代码更复杂。
答案 2 :(得分:-1)
这应该是一种优化,它使您的代码运行得更快,代价更低,因此更容易包含错误。在你的情况下,我不太明白代码的作用,但很明显有一个bug。并且很有可能编译器足够聪明,可以单独执行您要执行的操作。
通常,规则是:在测量代码速度后,只进行速度优化,发现速度太慢。如果它足够快,你没有费心测量速度,那么它足够快。然后在之前测量,在之后测量,并且只在速度上升时使用您的更改并且代码仍能正常工作。
您应该在代码中找到以不必要的复杂方式执行操作的位置,而不是使用降低代码质量的优化,而是以这种方式使事情变得更简单,更高效。删除不需要的并发症往往会使您的代码更正确,更易于维护和更快速。
答案 3 :(得分:-1)
使用register
对编译器进行微优化可能会使代码变慢,因为阻止编译器优化其所需的方式。
在性能问题上,尽量避免浪费大量时间(例如,当您可以通过引用传递它们时复制大对象),并且只有在证明(通过基准测试)时才需要优化。顺便说一下,基准测试将告诉你要优化什么。