Page 1 of 1

Reorder struct members to prevent padding

Posted: Wed Oct 11, 2023 3:27 pm
by ghost07
I've heard about structure padding to reduce R/W operations to access a struct member, and that there is "packed" option to disable this padding optimization.

I would like to write struct in certain order, to keep mutual parameters together.
But to apply reorder optimization at compilation to reduce used memory space while minimalizing R/W operations for most struct members.

Code: Select all

struct
{
    bool param1_enabled :1;
    int param1_value1;
    int param1_value2;
    
    bool param2_enabled :1;
    int param2_value1;
}
// size: 20

Code: Select all

struct __attribute__(__reorder__) // produces:
{
    // ints
    int param1_value1;
    int param1_value2;
    int param2_value1;
    
    // bools
    bool param2_enabled :1;
    bool param1_enabled :1;
}
// size: 13
Note: __reorder__ is made up, but I am looking for some attribute with this effect

I know that, according to C standard, compiler is not allowed to automatically reorder structure, but can I somehow explicitly ask it to do so for particular structure?

Re: Reorder struct members to prevent padding

Posted: Wed Oct 11, 2023 7:33 pm
by FrankSchwab
Not that I know of.
I know your pain, and have thought that this would be an excellent addition to 'C', especially in the embedded world, but sadly that's unlikely to happen.

Re: Reorder struct members to prevent padding

Posted: Wed Oct 11, 2023 7:38 pm
by MicroController
can I somehow explicitly ask it to do so for particular structure?
It appears that this is not possible a.t.m.

Re: Reorder struct members to prevent padding

Posted: Thu Oct 12, 2023 1:43 am
by HamGuy
Hello,
You are looking for #pragma pack and #pragma align. Do an internet search on both of these.

Regards,
Ron

Re: Reorder struct members to prevent padding

Posted: Thu Oct 12, 2023 7:20 pm
by MicroController
Problem with packing is that gcc will (on ESPs mostly unnecessarily) generate slow, byte-wise accesses, see e.g.
https://godbolt.org/z/nKc9Tcx4f
Notice that the access to what gcc determines to be an unaligned/packed uint32_t generates ten assembler instructions, compared to one instruction for a properly aligned struct member, or one or two for the possible "proper" access to the unaligned one.
Same thing for both Xtensa and RISC-V.

Re: Reorder struct members to prevent padding

Posted: Fri Oct 13, 2023 11:32 am
by ghost07
Wow I expected like only one or two more instructions for unaligned struct access, not 10 :D

However, in terms of speed, does one Assembler instruction take always at least one CPU clock tick? Can't it process some instructions at once? So the Assembler code may look slow, but actually it could be done in 2-3 clock ticks? But this is probably too complicated to be covered in this topic

So, reordering struct members could optimize memory usage and still be as fast as aligned struct access, right?
Too bad there is no option for such optimization in 2023

Re: Reorder struct members to prevent padding

Posted: Fri Oct 13, 2023 4:55 pm
by MicroController
ghost07 wrote:
Fri Oct 13, 2023 11:32 am
However, in terms of speed, does one Assembler instruction take always at least one CPU clock tick? Can't it process some instructions at once? So the Assembler code may look slow, but actually it could be done in 2-3 clock ticks?
Nope. It's as bad as it looks. AFAICT none of the ESPs can retire more than 1 instruction per clock cycle (per core). - Even worse: All that code needs to be loaded from slow flash memory, at least leaving less space in the cache for 'useful' code.
So, reordering struct members could optimize memory usage and still be as fast as aligned struct access, right?
Correct. Ordering members by size, biggest data types first, keeps alignment and can reduce or eliminate padding.