Data structure alignment is the way data is arranged and accessed in computer memory. It consists of two separate but related issues: data alignment and data structure padding. When a modern computer reads from or writes to a memory address, it will do this in word sized chunks (e.g. 4 byte chunks on a 32-bit system). Data alignment means putting the data at a memory offset equal to some multiple of the word size, which increases the system's performance due to the way the CPU handles memory. To align the data, it may be necessary to insert some meaningless bytes between the end of the last data structure and the start of the next, which is data structure padding.
For example, when the computer's word size is 4 bytes, the data to be read should be at a memory offset which is some multiple of 4. When this is not the case, e.g. the data starts at the 14th byte instead of the 16th byte, then the computer has to read two 4-byte chunks and do some calculation before the requested data has been read, or it may generate an alignment fault. Even though the previous data structure ends at the 14th byte, the next data structure should start at the 16th byte. Two padding bytes are inserted between the two data structures to align the next data structure to the 16th byte.
Definitions
A memory address a, is said to be n-byte aligned when n is a power of two and a is a multiple of n bytes. In this context a byte is the smallest unit of memory access, i.e. each memory address specifies a different byte. An n-byte aligned address would have log2(n) least-significant zeros when expressed in binary.
See this example.
Here is a structure with members of various types, totalling 8 bytes before compilation:
Code: Select all
struct MixedData
{
char Data1;
short Data2;
int Data3;
char Data4;
};
After compilation the data structure will be supplemented with padding bytes to ensure a proper alignment for each of its members:
Code: Select all
struct MixedData /* after compilation */
{
char Data1;
char Padding1[1]; /* For the following 'short' to be aligned on a 2 byte boundary */
short Data2;
int Data3;
char Data4;
char Padding2[3];
};
The compiled size of the structure is now 12 bytes. It is important to note that the last member is padded with the number of bytes required to conform to the largest type of the structure. In this case 3 bytes are added to the last member to pad the structure to the size of a long word.
It is possible to change the alignment of structures to reduce the memory they require (or to conform to an existing format) by reordering structure members or changing the compiler’s alignment (or “packing”) of structure members.
Code: Select all
struct MixedData /* after reordering */
{
char Data1;
char Data4; /* reordered */
short Data2;
int Data3;
};
The compiled size of the structure now matches the pre-compiled size of 8 bytes.
There different directives for aligning on different compilers.
On Visual C++, we use something like below.
Code: Select all
#pragma pack(push) /* push current alignment to stack */
#pragma pack(1) /* set alignment to 1 byte boundary */
struct MyPackedData
{
char Data1;
long Data2;
char Data3;
};
#pragma pack(pop) /* restore original alignment from stack */
if you use alinging for only one structure, we use,
Code: Select all
__declspec(align(32)) struct Str1{
int a, b, c, d, e;
};
On CCS, since most of the C6000s are 128 bit alinged, we use #pragma DATA_ALIGN(array_name, 128) before the declaration of array.