編譯之 記憶體對齊

2022-02-16 18:01:32 字數 1215 閱讀 4815

現代計算機中記憶體空間都是按照 byte 劃分的,也就是位元組,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊

從cpu的角度來說,cpu不會一次讀取或寫入乙個位元組的記憶體。相反,cpu一次以2、4、8、16或32位元組塊訪問記憶體。這樣做的原因是提公升效能:

訪問4位元組或16位元組邊界上的位址比訪問1位元組邊界上的位址快得多。

下圖說明了cpu如何以4位元組記憶體訪問粒度訪問4位元組資料

那麼如果資料/記憶體沒有對齊的話,則cpu必須執行額外的工作才能訪問資料,如下圖,cpu一次性訪問4個位元組:

沒有對齊的話就會經歷:

裝入2個資料塊,移出不需要的位元組,然後將它們組合在一起。此過程肯定會降低效能,浪費cpu週期,只是為了從記憶體中獲取正確的資料。

那麼現在的話,對齊這部分編譯器會幫我搞定,一般不需要自己動手,但也排除一些極端情況。在32位或者64位x86系統中,對齊方式與其資料型別的大小基本相同。編譯器在其自然長度邊界上對齊變數。 cpu就可以正確處理未對齊的資料。

舉乙個簡單的例子:

我們知道,int型別佔4個位元組的空間,char一般就是1個,如果把它們放在乙個結構體中,理論上佔 4+1=5個byte,但由於cpu的訪問和對齊的原因,實際上,預設情況下它會佔8個byte,可以sizeof以下就知道了

struct user;
原理如圖:

每個特定平台上的編譯器都有自己的預設「對齊係數」(也叫對齊模數)。可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16 來改變這一係數,其中 n 就是你要指定的「對齊係數」。

如果上面那個例子,對齊係數改成1,那麼就只占用5個byte,但這樣會使得cpu負擔更大

在某些情況下,通過為資料結構指定自定義對齊方式,可以顯著提高效能或節省記憶體.

C 深陷 之「記憶體對齊」

現代計算機在處理資料時,按照某個 單位 來處理。32位機器,每次處理32位 4位元組的二進位制資料,64位同理。記憶體對齊指的是計算機系統對基本資料型別合法位址做出了一些限制,要求某種型別物件的位址必須是某個值的倍數。本文著重於記憶體對齊的基本原理,有關複雜情況下 虛函式 繼承等 的記憶體對齊方案,...

C C 之記憶體對齊詳情

計算機系統對基本型別資料在記憶體中放的位置做了限制,它們會要求這些數的首位址是乙個數 一般為4和8 的整數倍,我們看下結構體的大小 include struct a int main 結果 1111demacbook pro digui a1111 sizeof size of struct a i...

程式設計基礎整理之記憶體對齊

記憶體對齊 最近學習c c 時,時常會被問到某一struct或者union的所佔記憶體空間的大小,主要涉及到記憶體對齊的問題。記憶體對齊應該是編譯器所幹的活。編譯器為程式中的每個 資料單元 安排在適當的位置上。但是c的乙個特點就是太靈活,太強大,它允許程式設計師去干預記憶體對齊。作為程式設計師要想去...