struct { /* Fileheader */
uchar file_version[4];
uchar options[2];
uchar header_length[2];
uchar state_info_length[2];
uchar base_info_length[2];
uchar base_pos[2];
uchar key_parts[2]; /* Key parts */
uchar unique_key_parts[2]; /* Key parts + unique parts */
uchar keys; /* number of keys in file */
uchar uniques; /* number of UNIQUE definitions */
uchar language; /* Language for indexes */
uchar max_block_size_index; /* max keyblock size */
uchar fulltext_keys;
uchar not_used; /* To align to 8 */
} header;
The above is extracted from MySQL source,
why bother to align to 8
?
It's an optimization to allow more efficient access to the structures in memory by the CPU.
http://en.wikipedia.org/wiki/Data_structure_alignment
Reason 1: Address computations are faster and smaller.
On x86 as well as some other architectures, it is more efficient to access elements of an array if the element size is a "nice, round number". For the definition of "nice, round number", learn x86 assembly. But you can see the effects of accessing arrays with differently sized elements in assembly for the following code:
struct s { char c[N]; };
int func(struct s *p, int i) { return p[i].c[0]; }
When N is 23 (size of the above structure without padding):
leaq (%rsi,%rsi,2), %rax
salq $3, %rax
subq %rsi, %rax
movsbl (%rax,%rdi),%eax
When N is 24 (size of the above structure with padding):
leaq (%rsi,%rsi,2), %rax
movsbl (%rdi,%rax,8),%eax
When N is 32 (size of the above structure with additional padding):
salq $5, %rsi
movsbl (%rsi,%rdi),%eax
Notice how complicated the code is for accessing an element in an array with 23-byte elements.
Reason 2: For on-disk structures, it allows other elements in file to be accessed with aligned loads and stores.
It looks like the structure appears on disk. With padding, a 32-bit word can appear directly after the structure and be aligned. This makes it faster to access -- the compiler automatically does this for structures in memory, but you need to do it manually for structures on disk. Some architectures will even crash if you try to access unaligned data.
unsigned char *data = ...;
header *h = (header *) data;
do_something_with(h);
uint32_t x = *(uint32_t *) (data + sizeof(header));
The above code will crash a SPARC if sizeof(header)
is not a multiple of 4, and on x86 it will be slower unless sizeof(header)
is not a multiple of 4.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With