過度對齊(over-alignment)
每種型別都有編譯器自動保證的自然對齊——例如 double 是 8 位元組。過度對齊是指你要求比這個自然需求「更強」的對齊,例如即使元素只需 8 位元組,仍把緩衝區強制放到 64 位元組邊界。這個詞就是在指「比型別通常要求更大的對齊」。
你用 alignas 請求過度對齊,例如 alignas(64) struct counters c,這會填充並定位物件,使其位址為 64 的倍數。標準把任何大於 alignof(max_align_t) 的對齊稱為「擴展對齊」,而某個擴展對齊是否被支援屬於實作定義行為。對動態記憶體而言,純 malloc 只保證適用於任何一般型別的對齊,所以要在堆積上配置過度對齊的物件,要用 aligned_alloc(alignment, size)(C11)或 posix_memalign,且仍須用 free() 釋放。
它在兩個重要場合派上用場:把各執行緒的熱門資料放到不同快取行以避免偽共享,以及滿足 SIMD 向量載入或 DMA 引擎對未對齊位址會出錯的硬體需求。誠實的提醒:過度對齊會在填充上浪費一些記憶體、malloc 取得的記憶體「不」保證過度對齊(請用 aligned_alloc),而且在許多實作上 aligned_alloc 要求大小是對齊值的倍數。
#include <stdlib.h> // 在堆積上配置 64 位元組對齊的 4 KiB 區塊: void *p = aligned_alloc(64, 4096); // 大小是 64 的倍數 // ... 使用 p ... free(p); // 仍然用 free() 釋放
malloc 不保證過度對齊;aligned_alloc 給出落在所選 2 的次方邊界上的區塊,照常以 free() 釋放。
某個特定的擴展(過度)對齊是否受支援屬於實作定義行為,而一般 malloc 不提供過度對齊保證——請用 aligned_alloc,並且結果仍以 free() 釋放。