Struct overheads?

I just heard from our teacher that accessing struct members has a useless overload and that it's caused by something called overhead. If someone knows what are these 2 terms when relating to structs would be great lol.
It does not. It may have way way back in the day, but there is no overhead now. The compiler knows that object.item is just a memory location, and it uses the memory location directly if it can. The compiler does more work, but your program won't.

Overhead is when your program does something behind the scenes that costs CPU, memory, etc resources without your permission or knowledge.

Functions have overhead:

int foo(int x) // this will, behind the scenes, perform some tasks like pushing the current register set (assuming it can't be inlined here) and setting the registers up for the foo code block).


Structs and classes with pure data and no weird alignment settings have no overhead to directly access the data.

However, direct access is generally considered bad style, and functional access is preferred. This costs you if the function is not cleanly inline, which it sometimes cannot be.

And this is 2017. The extra 10 or 15 cpu cycles isnt even a whole nanosecond anymore. You need billions, possibly trillions of items to access in a loop before you notice these things on a modern machine.

Last edited on
Thanks!
There may be an overhead to access a member of the struct which is at a non-zero offset.
address of member == address of struct + offset of member
It may not always be possible to optimise this away.

For instance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int foo( int a, int b )
{
    return a + b ;

    /*
        lea     eax, [rdi+rsi]
        ret
   */
}

struct S { int a ; int b ; };

int bar( S s )
{
    return s.a + s.b ;

    /*
        mov     rax, rdi
        sar     rax, 32
        add     eax, edi
        ret
    */
}

int baz( const S& s )
{
    return s.a + s.b ;

    /*
        mov     eax, DWORD PTR [rdi+4]
        add     eax, DWORD PTR [rdi]
        ret    
    */
}

https://godbolt.org/g/CxYSWC
the diff between foo(int a, int b) and bar(S s) is really due to the 64bit calling convention: named parameters are always passed in separate CPU registers (rdi and rsi here, since this is the SysV ABI), while structs are packed: this struct happens to fit entirely in the rdi CPU register.

Depending on what you do with them, it could mean passing variables separately has overhead (increased register pressure)
Last edited on
can't you control packing and alignment with compiler flags?
To control alignment, we can use the alignas specifier.

For instance: struct S { alignas(long long) int a ; alignas(long long) int b ; };

https://godbolt.org/g/pG8wQK

Using packing that is different from the natural packing on the platform may save memory, but would typically lead to less efficient code.
I was thinking the other direction, forcing everything to the same width, losing memory to (possibly) gain time.
Topic archived. No new replies allowed.