Game Engine Architecture

(Ben Green) #1

124 3. Fundamentals of Software Engineering for Games


or class, the compiler introduces padding (holes) in order to ensure that every-
thing is properly aligned. It’s a good idea to think about alignment and pack-
ing when declaring your data structures. By simply rearranging the members
of struct InefficientPacking from the example above, we can eliminate
some of the wasted padding space, as shown below and in Figure 3.15:

struct MoreEfficientPacking
{
U32 mU1; // 32 bits (4-byte aligned)
F32 mF2; // 32 bits (4-byte aligned)
I32 mI4; // 32 bits (4-byte aligned)
char* mP6; // 32 bits (4-byte aligned)
U8 mB3; // 8 bits (1-byte aligned)
bool mB5; // 8 bits (1-byte aligned)
};
You’ll notice in Figure 3.15 that the size of the structure as a whole is
now 20 bytes, not 18 bytes as we might expect, because it has been padded
by two bytes at the end. This padding is added by the compiler to ensure
proper alignment of the structure in an array context. That is, if an array of
these structs is defi ned and the fi rst element of the array is aligned, then the
padding at the end guarantees that all subsequent elements will also be aligned
properly.
The alignment of a structure as a whole is equal to the largest alignment
requirement among its members. In the example above, the largest mem-
ber alignment is four-byte, so the structure as a whole should be four-byte

CPU

alignedValue

0x6A341170
0x6A341174
0x6A341178

register

-alignedValue

0x6A341170
0x6A341174
0x6A341178

un-

-alignedValue

shift un-
shift

un- -alignedValue

Aligned read from
0x6A341174

Unaligned read from
0x6A341173

CPU
register

Figure 3.14. Aligned and unaligned reads of a 32-bit integer.

(pad)

mU1
mF2

mB3

mI4

mB5

mP6

+0x0
+0x4
+0x8
+0xC
+0x10


Figure 3.15. More ef-
fi cient packing by
grouping small mem-
bers together.

Free download pdf