Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Memory alignment - should we care? [duplicate]

Consider working on an x64 bit Windows operation system with the following type alignments:

C++ build in types alignments on my pc

As far as I understand, it is very bad to do something like this:

struct X_chaotic
{
    bool flag1;
    double d1;
    bool flag2;
    double d2;
    bool flag3;
    double d3;
    //... and so on ...
};

According to C++ Alignment, Cache Line and Best Practice and Data structure alignment, it should be better/faster and much more compact to write this:

struct X_alignOrder
{
    double d1;
    double d2;
    double d3;
    //... all other doubles ...
    bool flag1;
    bool flag2;
    bool flag3;
    //... all other bools ...
};

The members are declared in the order of the alignment size, starting with the highest alignment.

Is it safe to say it is a good idea to order the declaration of the data members by alignment size? Would you say it is best practice? Or does it make no difference?

(I heard that the compiler can not rearrange the defined order, due to the C++ standard, and this even holds for all data members declared in access specifier blocks of a class)

Because I never read about this, neither in Scott Meyers' books nor in Bjarne Stroustrup's books, I wonder if I should start reordering the data declarations by alignment for my day-to-day work.

like image 927
user1911091 Avatar asked Feb 11 '26 23:02

user1911091


2 Answers

This is more complicated than it may seem.

By ordering your members according to alignment needs you'll save some padding bytes and the total size will be smaller. This may be important to you if memory is tight or if this means the type can fit in a single cache line rather than two or three.

On the other hand; if you often access members that used to be close together so they would often be pulled into cache together by the CPUs prefetcher before, but now won't after reorganizing the class. Then you could be saving memory but sacrificing runtime performance.

Performance here may also vary greatly across different CPUs and different compilers/compiler options.

You'll need to run some benchmarks in your actual environment to see what performs the best for you.

Also keep in mind that reshuffling your member variables changes the order of initialization, which can be important if members depend on each other (foo initializes bar, so foo needs to be initialized first, etc).

like image 193
Jesper Juhl Avatar answered Feb 15 '26 03:02

Jesper Juhl


Yes. In theory, the alignment of your data structures matters if you are concerned about the performance. It is good programming practice as well.

Most of the time, the alignment of your data structure is set based on the widest member of the 'struct'. Normally, your compiler takes care of it for you. The behaviour, however, can be different for C++ and C when in comes to inserting leading padding.

You can use the offsetof macro to evaluate the distance of a given struct member in size_t. This is ANSI C, though.

#include <stdio.h>
#include <stddef.h>

typedef struct Test_t {
    char *p;
    char c;
    int i;
    long l;
} Test;

int main(){
    printf("offsetof(Test,p) = %zu\n", offsetof(Test,p));
    printf("offsetof(Test,c) = %zu\n", offsetof(Test,c));
    printf("offsetof(Test,i) = %zu\n", offsetof(Test,i));
    printf("offsetof(Test,l) = %zu\n", offsetof(Test,l));
    return 0;
}

This will print

offsetof(Test,p) = 0
offsetof(Test,c) = 8
offsetof(Test,i) = 12
offsetof(Test,l) = 16
like image 22
fnisi Avatar answered Feb 15 '26 02:02

fnisi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!