Reputation: 455
I'm working on a memory pool implementation and I'm a little confused about pointers alignment...
Suppose that I have a memory pool that hands out fixed size memory blocks, at the point of memory pool creation I malloc((size)*(num of blocks)). If what's being allocated are objects and the size comes from the sizeof operator alignment shouldn't be a concern, but if the size is uneven (he/she wants 100 byte blocks for whatever reason), then when I split the chunk given by malloc I'd end up with unaligned pointers. My question is should I always align the blocks to some boundary and if yes which?
Upvotes: 2
Views: 428
Reputation: 882791
Proper alignment is at least helpful (performance-wise) on most x86 implementations (and some kind of alignment is actually mandatory in other architectures). You might ask (like calloc does) for a pair of arguments, size of items in bytes and number of items, rather than just one (size in bytes, like malloc does); then you can intrinsically align (by rounding up block sizes) to the next-higher power of 2 above the item size (but switch to multiples of 16 bytes above 16, don't keep doubling forever, just like @derobert recommends and explains!-). This way, if a caller just wants N bytes w/o any alignment nor padding, they can always ask for N items of 1 byte each (just like they would with calloc and for the same reason;-).
Upvotes: 3
Reputation: 51207
X86 will work without alignment, but performance is better when data is aligned. Alignment for type is generally sizeof(type), up to a maximum of 16 (bytes).
I wrote this silly test program just to be sure (asuming malloc knows what its doing), and it returns 16 on my amd64 box. It returns 8 when compiled in 32-bit mode:
#include <stdlib.h>
#include <stdio.h>
int main() {
int i;
unsigned long used_bits = 0, alignment;
for (i = 0; i < 1000; ++i) {
used_bits |= (unsigned long)malloc(1); /* common sizes */
used_bits |= (unsigned long)malloc(2);
used_bits |= (unsigned long)malloc(4);
used_bits |= (unsigned long)malloc(8);
used_bits |= (unsigned long)malloc(16);
used_bits |= (unsigned long)malloc(437); /* random number */
}
alignment = 1;
while (!(used_bits & alignment)) {
alignment <<= 1;
}
printf("Alignment is: %lu\n", alignment);
return 0;
}
Upvotes: 2