記憶體對齊的思考

2021-09-30 13:31:31 字數 1130 閱讀 5709

最近讀了traffic server原始碼裡的iobuffer***結構體 裡面涉及到memalign函式

搜尋了一下 居然發現nginx裡也使用了記憶體對齊

資料的對齊(alignment)是指資料的位址和由硬體條件決定的記憶體塊大小之間的關係。乙個變數的位址是它大小的倍數的時候,這就叫做自然對齊 (naturally aligned)。例如,對於乙個32bit的變數,如果它的位址是4的倍數(乙個位址標識乙個位元組),--  就是說,如果位址的低兩位是0,那麼這就是自然對齊了。所以,如果乙個型別的大小是2n個位元組,那麼它的位址中,至少低n位是0。對齊的規則是由硬體引起 的。一些體系的計算機在資料對齊這方面有著很嚴格的要求。在一些系統上,乙個不對齊的資料的載入可能會引起程序的陷入。在另外一些系統,對不對齊的資料的 訪問是安全的,但卻會引起效能的下降。在編寫可移植的**的時候,對齊的問題是必須避免的,所有的型別都該自然對齊

一般情況下 編譯器和c庫處理了對齊問題。posix  標明了通過malloc( ), calloc( ), 和 realloc( )  返回的位址對於任何的c型別來說都是對齊的。即:位址都是某個數的整數倍  在linux中,這些函式返回的位址在32位系統是以8位元組為邊界對齊,在64位系統是以16位元組為邊界對齊 的。

有時候,對於更大的邊界,例如頁面,程式設計師需要動態的對齊 這時得需要posix 1003.1d提供乙個叫做posix_memalign( void **memptr,size_t alignment, size_t size)的函式成功返回size位元組的動態記憶體,並且這塊記憶體的位址是alignment的倍數。引數alignment必須是2的冪(把它當做不同的型別),還是void指標的大小的倍數。返回的記憶體塊的位址放在了memptr裡面,函式返回值是0. 更直白點就是 size大小的記憶體 必須按alignment對齊

呼叫失敗時,沒有記憶體會被分配,memptr的值沒有被定義,返回如下錯誤碼之一:

einval  引數不是2的冪,或者不是void指標的倍數。

enomem 沒有足夠的記憶體去滿足函式的請求。

要注意的是,對於這個函式,errno不會被設定,只能通過返回值得到。

memalign (getpagesize ( ), sizeof (struct ***)); 返回一塊足夠大的記憶體去容納乙個結構體,並且位址都是在乙個頁面的邊界上.

參考鏈結 

記憶體對齊 記憶體對齊規則解釋 記憶體對齊原理

一 記憶體對齊的原因 我們都知道計算機是以位元組 byte 為單位劃分的,理論上來說cpu是可以訪問任一編號的位元組資料的,我們又知道cpu的定址其實是通過位址匯流排來訪問記憶體的,cpu又分為32位和64位,在32位的cpu一次可以處理4個位元組 byte 的資料,那麼cpu實際定址的步長就是4個...

記憶體對齊(自然對齊)

參考 今天與超,暉,棟,宇幾人論此問題,終得以下結論,不知正確與否,姑且記下。對於32位機,cpu的記憶體讀寫週期是4word,所以在記憶體對齊時,皆以此填滿。如 struct a char a double b char c sizeof a 4 8 4 16 struct b char a do...

位元組對齊 記憶體對齊 對齊粒度

其實標題裡面的三個關鍵字說的都是同乙個東西。也就是c 中類和結構體在記憶體中的分配策略,專業術語可以稱之為 對齊模數 alignment modules 對齊模數分為三類 1.自身對齊模數,也就是類或結構體中成員的大小,1,2,4,8之中的乙個,對應byte word dword qword。2.指...