在C / C ++中,与隔离变量相比,访问struct成员是否有任何CPU开销?
对于一个具体的例子,下面的第一个代码示例是否应该使用比第二个更多的CPU周期?如果它是一个类而不是一个结构,它会有什么不同吗? (在C ++中)
1)
struct S {
int a;
int b;
};
struct S s;
s.a = 10;
s.b = 20;
s.a++;
s.b++;
2)
int a;
int b;
a = 10;
b = 20;
a++;
b++;
答案 0 :(得分:8)
“不要优化。”编译器会为您找出最佳案例。首先写下有意义的内容,如果需要,可以在以后加快速度。为了好玩,我在Clang 3.4(-O3 -S)中运行了以下内容:
void __attribute__((used)) StructTest() {
struct S {
int a;
int b;
};
volatile struct S s;
s.a = 10;
s.b = 20;
s.a++;
s.b++;
}
void __attribute__((used)) NoStructTest() {
volatile int a;
volatile int b;
a = 10;
b = 20;
a++;
b++;
}
int main() {
StructTest();
NoStructTest();
}
StructTest
和NoStructTest
具有相同的ASM输出:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl $10, -4(%ebp)
movl $20, -8(%ebp)
incl -4(%ebp)
incl -8(%ebp)
addl $8, %esp
popl %ebp
ret
答案 1 :(得分:2)
没有。 struct
中所有类型的大小,以及struct
开头的每个成员的偏移量,在编译时都是已知的,因此用于获取{中的值的地址{1}}与各个变量的地址一样可以理解。
答案 2 :(得分:1)
我的理解是结构中的所有值都在内存中相邻,并且能够比变量更好地利用内存缓存。
变量也可能在内存中相邻,但它们不能保证像结构一样相邻。
话虽如此,在决定是否首先使用结构时,不应考虑cpu性能。
答案 3 :(得分:0)
真正的答案是:它完全取决于您的CPU架构和编译器。最好的方法是编译并查看汇编代码。
现在对于x86机器,我很确定没有。偏移量计算为编译时间,并且存在具有一些偏移量的地址模式。
答案 4 :(得分:-1)
如果您要求编译器进行优化(例如使用gcc -O2
或g++ -O2
进行编译),则没有太多开销(可能太小而无法测量,或者可能只有几个百分点)。
但是,如果仅使用局部变量,则优化编译器甚至可能不会在本地call frame中为它们分配插槽。
与gcc -O2 -fverbose-asm -S
编译并查看生成的汇编代码。
使用class
不会有任何区别(当然,有些class
- 有昂贵的构造函数和析构函数)。
这样的代码在生成的C或C ++代码中很有用(如MELT所做的那样);本地这样的struct
- s或class
- es包含本地调用帧(如MELT语言所示,参见例如其gcc/melt/warmelt-genobj+01.cc生成的文件)。我并不认为它与真正的C ++局部变量一样高效,但它得到了足够的优化。