2017-08-31 128 views

回答

1

這些是兩個獨立因素:size指示原始大小,align只是分配塊的位置。在實際的代碼中你可能會看到一個關聯,你想要某種對齊的原因通常是因爲size是某個因素的偶數倍,但這並不是一個硬性要求。

您可能有一個完全有效的理由來分配79個字節對齊在8個字節的基礎上。

+0

對此有何參考? –

+0

鑑於未定義的行爲非常重要,所以在相關時總會提到它(例如,使指針無效),以及在該函數的文檔中沒有提及它,因此沒有理由相信未定義行爲是一個因素。這只是一個分配器,沒有什麼奇特的。如果你想分配一些非常奇怪的東西,那不是未定義的行爲,但是如果你在其中放置了錯誤對齊的結構,它可能會導致未定義的行爲。 – tadman

1

英特爾的文檔_mm_mallocin their own compiler只說「這[對齊]約束必須是2的冪」。

沒有要求大小爲對齊的倍數,因爲它的主要用例是SIMD,分配數組的對齊大於單個成員的寬度是完全正常的。 (例如,對於AVX,對應於32B的float*)。或者用於緩存行/頁面/巨大頁面的邊界。例如爲了更好地利用透明的巨大頁面,您可以爲大於2MB的分配使用2MB對齊方式進行分配。

唯一對齊分配器我所知道的是確實有你擔心的限制是C11/C++17 aligned_alloc,這是不幸的是在需要時size % align != 0失敗。在How to solve the 32-byte-alignment issue for AVX load/store operations?上查看我的回答。 TL; DR:最初的C11 aligned_alloc是具有非多對齊大小的UB,所以真實的實現選擇使其如同其他對齊的分配器一樣工作(例如posix_memalign)。但是後來它被更改爲要求在這種情況下失敗(返回一個錯誤),而不是UB,所以允許它工作的實現在技術上違反了(愚蠢的)標準。 C++ 17具有要求失敗的版本。

很顯然,英特爾並沒有犯與標準委員會所做的aligned_alloc相同的錯誤,因爲它會打敗_mm_malloc優化的目的。當然,他們考慮了SIMD和內存邊界的使用情況。 (IDK的標準委員會如何不是,它看起來非常明顯,它們是類型/緩衝區的主要用例,它比最寬類型的自然對齊更具有對齊性。真正令人失望的是,具有最佳API的一個函數並不安全使用。(aligned_alloc回報內存freeable與free,並且不採取指針的地址,像posix_memalign輸入(這會導致編譯器擔心別名)擊敗優化。)

還是會分配下一個比較大的字節數是多少?

這對32B或64B等小對齊可能有效。根據具體實施情況,它可能不會將最後的鬆散空間用於較小的分配,其中malloc或較小的對齊呼叫_mm_malloc。讀取對齊邊界沒有錯誤(如果它小於4k頁面)是安全的,但如果沒有明確分配它,則不要寫入它。

在任何高質量的實現中,大型對齊會浪費多個整個頁面是極不可能的。您總是可以通過執行大量分配(如_mm_malloc(3M, 2M))和一些可以使用該分配空間(如_mm_malloc(512k, 4k)),然後sleep(100)的分配來進行測試。在退出之前查看進程的內存佔用情況。

相關問題