[英]x86 Memory Alignment of struct vs. cache line?
最近我正在研究一個“搜索系統”,而關於內存/緩存性能的一些事情讓我感到困惑。 假設我的機器信息:x86 arch(L1-3 緩存,64 字節緩存線),linux 操作系統
CPU每次讀取64個字節(緩存行),那么CPU從內存地址(到緩存)讀取數據是否總是64倍?例如0x00(到0x3F),0x40(到0x7f)。 如果我需要位於 0x20 的數據(int32_t),那么系統仍然需要加載 0x00--0x3F。 這個案子怎么樣:
struct Obj{int64_t a[5];char b[2];};
然后定義int64_t c[5]; Obj obj; int64_t d;
虛擬內存(或物理內存?)會像這樣組織嗎?
我認為您可能缺少的部分是編譯器對各種類型強加的對齊要求。
整數類型通常與其自身大小的倍數對齊(例如,64 位整數將與 8 個字節對齊); 所謂的“自然對齊”。 這不是 x86 的嚴格架構要求; 未對齊的加載和存儲仍然有效,但由於它們效率較低,編譯器傾向於避免它們。
一個聚合,就像一個struct
,根據其成員的最高對齊要求對齊,如果需要,將在成員之間插入填充以確保每個成員正確對齊。 填充也將在最后添加,以便struct
的整體大小是其所需對齊的倍數。
因此,在您的示例中, struct Obj
對齊方式為 8,其大小將四舍五入為 48(末尾有 6 個字節的填充)。 因此不需要在c[4]
之后插入 24 個字節的填充(我認為您打算在地址 40-63 處寫入填充); 您的obj
可以放在地址 40。然后可以將d
放在地址 88。
請注意,這些都與緩存行大小無關。 默認情況下,對象不與緩存行對齊,盡管“自然對齊”將確保沒有整數加載或存儲必須跨越緩存行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.