Znorg
Znorg

Reputation: 711

CPU overhead for struct?

In C/C++, is there any CPU overhead for acessing struct members in comparison to isolated variables?

For a concrete example, should something like the first code sample below use more CPU cycles than the second one? Would it make any difference if it were a class instead of a struct? (in 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++;

Upvotes: 10

Views: 2554

Answers (5)

If you ask the compiler to optimize (e.g. compile with gcc -O2 or g++ -O2) then there are no much overhead (probably too small to be measurable, or perhaps a few percents).

However, if you use only local variables, the optimizing compiler might even not allocate slots for them in the local call frame.

Compile with gcc -O2 -fverbose-asm -S and look into the generated assembly code.

Using a class won't make any difference (of course, some class-es have costly constructors & destructors).

Such a code could be useful in generated C or C++ code (like MELT does); local such struct-s or class-es contain the local call frame (as seen by the MELT language, see e.g. its gcc/melt/warmelt-genobj+01.cc generated file). I don't claim it is as efficient as real C++ local variables, but it gets optimized enough.

Upvotes: -1

Sam Cristall
Sam Cristall

Reputation: 4387

"Don't optimize yet." The compiler will figure out the best case for you. Write what makes sense first, and make it faster later if you need to. For fun, I ran the following in 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 and NoStructTest have identical ASM output:

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

Upvotes: 16

Emmet
Emmet

Reputation: 6421

No. The size of all the types in the struct, and thus the offset to each member from the beginning of the struct, is known at compile-time, so the address used to fetch the values in the struct is every bit as knowable as the addresses of individual variables.

Upvotes: 4

hivert
hivert

Reputation: 10667

The real answer is: It completely depend on you CPU architecture and your compiler. The best way is to compile and look at the assembly code.

Now for x86 machine, I'm pretty sure there isn't. The offset is computed as compile time and there is an adressing mode with some offset.

Upvotes: 0

My understanding is that all of the values in a struct are adjacent in memory, and are better able to take advantage of the memory caching than the variables.

The variables are probably adjacent in memory too, but they're not guaranteed to be adjacent like the struct.


That being said, cpu performance should not be a consideration when deciding whether to use or not use a struct in the first place.

Upvotes: 2

Related Questions