GNU檔案宣告在malloc64 位系統上與 16 位元組倍數對齊。為什么是這樣?
如果我的理解是正確的,那么暫存器和所有指令都對最大 8 位元組寬的值進行操作。因此,似乎需要 8 位元組對齊。
筆記:
- 我找到了為什么堆疊指標必須是 16 位元組對齊而不是其他記憶體地址的一些理由
- 我看到一些評論者說這只是為了減少內部碎片,這沒有多大意義,因為檔案指出他們專門針對
x86_64
uj5u.com熱心網友回復:
x86_64 使用 xmm 暫存器(大量 - 所有 fp 內容都在 xmm 暫存器中完成,因為不推薦使用 8087 fp 暫存器),并且 xmm 暫存器需要 16 位元組對齊才能(有效)訪問。
所以 x86_64 中的大多數東西(包括 malloc 分配的堆疊和堆)都被組織為始終是 16 位元組對齊的,因此當涉及 xmm 暫存器時編譯器總是可以自由使用“對齊”指令而無需使用(可能更慢)未對齊的指令。
uj5u.com熱心網友回復:
x86-64 System V 將 x87 用于long double80 位型別。并將其填充到 16 位元組,alignof(long double) == 16這樣長的雙精度將永遠不會越過快取線邊界。(無論是否值得,IDK;可能 SSE2 是廉價支持 16 位元組對齊的動機之一)。
但無論如何,SSE 的東西并不是唯一的貢獻alignof(max_align_t) == 16(它設定了 malloc 允許回傳的最小對齊)。
的存在__m128i根本沒有直接貢獻max_align_t,例如 32 位 C 實作以較低的 malloc 保證支持它。當然,支持 AVX 的系統的存在__m256i并沒有增加分配器的對齊保證。(如何解決 AVX 加載/存盤操作的 32 位元組對齊問題?)。但是,對于自動和手動向量化來說,分配的記憶體足夠對齊當然很方便movaps,尤其是在舊 CPU 上,當 x86-64 是新的并且movups即使記憶體對齊也會受到懲罰。如果編譯器只看到 a ,則很難利用該保證float*,您可以將指標傳遞給分配的中間。但如果它可以看到malloc 對于輸出陣列,它知道如果自動矢量化寫入該新分配空間的回圈,它將對齊。
順便說一句,ISO C 將允許malloc小分配(如 1 到 15 個位元組)回傳對齊較少的空間,因為該空間仍可用于保存任何適合的型別。在 C 中,一個物件不能比它的大小需要更多的對齊。(例如,您不能 typedefint總是必須在快取行的開頭,或者如果您使用填充進行 sizeof 擴展。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/410338.html
標籤:
