Padding Bytes, Why Should You Care About It?

This is part of Gopher UnderCover Series.
Before discussing about padding bytes let’s first investigate why we need it, in the first place.
For this i am assuming we are having 64 bit architecture machine.
type Foo struct{
isValid bool
id int16
value int32
}
So, How Much Memory Will this struct will take?
bool → 1 bytes, int16 → 2 bytes , int32 → 4 bytes => 7 bytes.
No, this will take 8 bytes memory. But why? it takes extra 1 bytes.
Because there is memory alignment thing, which compiler has to take care about.
To make 8 bytes memory block filled, compiler adds extra padding bytes.

Why This Happen?
From a hardware perspective, have to make sure memory always align in certain boundaries. To minimize amount of operation to get data from hardware.
Let’s don’t follow memory alignment.

In above, Diagram 2bytes of integer is in Block A where rest of 2 in Block B. So, to get data hardware have to perform 2 operation just to get that data, which is waste of 1 cpu cycle. we can have done in 1.
For 1 byte data, it can be place anywhere, when data is more than 1 byte, it have to follow alignment, to make sure we don’t increase operation of hardware to get data.
Alignment make sure, that data store in sequential manner in memory and store in same memory block.

As per size of data type, alignment is assigned by compiler.
int 16 → 2 bytes alignment.
Why Should You Care About?
In most of the cases, you don’t need to care about how this form. But in profiling program some performance issue comes, there you need to care.Some time there may form too much of extra padding bytes.
Let Change our Struct.
type Foo struct{
isValid bool
id int64
value int64
anotherVal float32
}
There is rule, whichever is larger datatype in struct, alignment will follow that. So, here 8 byte alignment will be allocated.
here, 1 byte + 7 padding bytes + 8 bytes+8 bytes+4 bytes => 28 bytes. we have to take data in 8 bytes but 28 is not divisible by 8. So, we have add extra 4 padding bytes. which makes → 32 bytes.
Which visual representation is something like:

So, we have 11 bytes of padding byte.
There is trick, write struct as largest value at first.
type Foo struct{
id int64
value int64
anotherVal float32
isValid bool
}

Now, 8 bytes + 8 bytes + 4 bytes + 1 bytes = 21 bytes (which is not divisible by 8) so we add , 21 bytes + 3 bytes = 24 bytes. So we save 6 bytes. By just changing way of defining struct.
Do this if only if it making impact on performance of your program, otherwise you don’t need to do premature optimization.





