内存对齐分配
某些硬件和系统调用要求内存按特定边界对齐(如 16 字节对齐用于 SIMD,页对齐用于内存映射)。C99 的 aligned_alloc(C11)和 POSIX 的 posix_memalign 提供对齐分配功能。
posix_memalign(POSIX)
#include <stdlib.h>
void *p;
int result = posix_memalign(&p, 64, 1024); /* 64 字节对齐,1024 字节 */
if (result == 0) {
/* p 是 64 字节对齐的 */
printf("%p\n", p); /* 地址低 6 位为 0 */
free(p);
}
aligned_alloc(C11)
#include <stdlib.h>
/* C11 标准 */
void *p = aligned_alloc(64, 1024); /* 64 字节对齐 */
if (p != NULL) {
/* 使用 */
free(p);
}
手动对齐
void *aligned_malloc(size_t size, size_t alignment)
{
void *p = malloc(size + alignment + sizeof(void *));
if (p == NULL) return NULL;
/* 计算对齐地址 */
void *aligned = (void *)(((size_t)p + alignment + sizeof(void *))
& ~(alignment - 1));
/* 存储原始地址 */
((void **)aligned)[-1] = p;
return aligned;
}
void aligned_free(void *p)
{
if (p != NULL)
free(((void **)p)[-1]);
}
应用场景
SIMD 指令:
/* SSE 需要 16 字节对齐 */
float *data = aligned_alloc(16, 64 * sizeof(float));
/* AVX 需要 32 字节对齐 */
float *data = aligned_alloc(32, 64 * sizeof(float));
DMA 传输:
/* 某些 DMA 需要页对齐 */
void *buffer = aligned_alloc(4096, 4096);
最佳实践
- 需要特殊对齐时用
posix_memalign或aligned_alloc - SIMD 数据按指令集要求对齐(SSE:16, AVX:32, AVX-512:64)
- 对齐大小必须是 2 的幂
- 对齐分配的内存用对应方式释放
- 普通数据用
malloc即可