內存地址對齊

電腦雜談  發布時間:2021-03-13 06:14:10  來源:網絡整理

內存地址對齊是一種安排和訪問計算機內存中數據的方法。它由兩個獨立且相互關聯的部分組成:基本數據對齊和結構數據對齊。當今的計算機在計算機內存中讀寫數據時以字長為單位進行操作(在32位系統中,數據總線寬度為32,并且每次可以讀取4個字節,而地址總線寬度為32,因此最大尋址空間為2 ^ 32 = 4GB,但是最低的2位A [0],A [1]不用于尋址,A [2-31]只能連接到內存,因此只能訪問4個空間,但總尋址空間仍為2 ^ 30 *字長= 4GB,因此,存儲在存儲器中的所有基本類型數據的首地址的最低兩位為0(結構中的成員變量除外)。數據對齊的基本類型意味著存儲器中數據的偏移地址必須等于一個字的倍數。這種存儲數據的方式可以提高讀取數據時的系統性能。為了對齊數據,可能有必要在前一個數據的末尾和下一個數據的開始處插入一些無用的字節。這是結構數據對齊。

例如,假設計算機的字長為4個字節,那么內存中變量的首地址滿足4地址對齊方式,并且CPU每次只能讀取4的倍數的地址。它可以讀取4個字節的數據。假設整數數據a的第一個地址不是4的倍數(如下圖所示),可以將其設置為0X00FFFFF3,然后將整數數據存儲在地址空間為0X00FFFFF3?0X00FFFFF6的存儲空間中,并且僅CPU可以讀取4的倍數的內存地址,因此,如果要讀取a的數據,則CPU必須在0X00FFFFF0和0X00FFFFF4讀取兩次內存,并且還要對兩次讀取的數據進行處理才能獲得,并且程序的瓶頸通常不是CPU的速度,而是取決于內存的帶寬,因為CPU的處理速度比從內存中讀取數據的速度快得多,因此降低了訪問內存空間是提高程序性能的關鍵。從上面的示例可以看出,采用內存地址對齊策略是提高程序性能的關鍵。

示例:

首先,讓我們看一下以下C語言結構:

typedef struct MemAlign
{
    int a;
    char b[3];
    int c;
}MemAlign;

以上結構占用多少內存?也許您會說這很簡單。計算每種類型的大小并將它們加在一起。以32平臺為例,int類型占用4個字節,而char占用1個字節,因此:4 + 3 + 4 =11。然后此結構總共占用11個字節的空間。好吧,然后我們通過實踐證明它是否正確,我們使用sizeof運算符查找該結構占用的內存空間大小sizeof(MemAlign),出乎意料的是,結果是12?看來我們錯了嗎?當然不是,但是這種結構已經過優化。此優化的另一個名稱為“ Alignment”。那么這種對齊方式做了什么樣的優化呢?讓我慢慢解釋。在解釋之前,讓我們看一張照片。 ,圖片如下:

內存地址圖

我相信學習匯編的朋友對此幅照片很熟悉。此圖是CPU和內存如何交換數據的模型。其中,左邊的藍色框是CPU,右邊的綠色框是內存。上面的0?3是內存地址。在這里,我們的圖片由32位CPU表示。我們都知道32位CPU使用DWORD作為數據傳輸的單位。正是由于這個原因,引起了另一個問題。那么問題是什么呢?問題是,由于32位CPU以雙字形式傳輸數據,如果我們的數據只有8位或16位數據,CPU是否根據我們數據的位數進行數據傳輸?答案是不。如果這會使CPU硬件變得更加復雜,則32位CPU會以雙字方式傳輸數據,而不管它是8位還是16位數據傳輸。沒關系,可以傳輸8位或16位,但是事情并沒有我們想象的那么簡單。例如,如果在上圖中將4字節的int類型數據放置在內存地址1的開頭,則該數據將被占用。內存地址為1?4,則此數據分為2部分,一部分在地址0?3中,另一部分在地址4?7中,由于32位CPU以雙字傳輸,因此,一旦首先讀取地址0至3中的內容,CPU將被讀取2次。 ,然后再次讀取地址4到7中的數據。最后,CPU提取并組合正確的int類型數據,并丟棄不相關的數據。反過來說,如果我們將這個int類型的4字節數據放在上圖中從地址0開始的位置,該怎么辦?讀完此書后,也許您了解了,CPU只能通過讀取一次來獲取此int型數據。是的,就是這樣。這次,CPU僅花費一個周期來獲取數據。這說明了存儲數據的重要性。放置正確的位置可以減少對CPU資源的使用。

那么,內存對齊的原理是什么?我總結了一下,大致分為三個部分:

第1條:第一個成員的第一個地址為0

第2條:每個成員的第一個地址是其自身大小的整數倍

第二個補充:以4字節對齊為例,如果其大小大于4字節,則對齊基于4字節的整數倍。

第三篇文章:最后,整個結構是對齊的。

第三個補充:以4字節對齊為例,采用結構中最大成員類型的倍數。如果超過4個字節,則對齊基于4個字節的整數倍。 (該項目的名稱也為“互補”?;パa的目的是在多個結構變量彼此相鄰放置時滿足對齊要求。)

以上三個原則聽起來很抽象,所以讓我們使用一個示例來加深對內存對齊概念的理解。以下是結構。讓我們算出以下結構占用多少內存?假設我們在32位平臺上并對齊4個字節:

#pragma pack(4)
typedef struct MemAlign
{
    char a[18];
    double b;    
    char c;
    int d;    
    short e;    
}MemAlign;

下圖顯示了對齊的結構,如下所示:

內存地址圖

我們將使用這張圖片來說明如何對齊:

第一個成員(字符a [18]):首先,假設我們將其放在內存起始地址0。由于第一個成員占用18個字節,因此第一個成員占用內存地址,范圍為0-18。

第二個成員(雙精度b):由于雙精度類型占用8個字節,并且由于8個字節大于4個字節,因此4字節對齊方式是基準。由于第一個成員的結束地址是18,所以地址18不是4的整數倍。我們需要再添加2個字節,即,將第二個成員放在地址20處。

第三個成員(char c):由于char類型占用1個字節,因此任何地址都是1個字節的整數倍,因此我們可以將其直接放置在第二個成員之后。

第四個成員(int d):由于int類型占用4個字節,但是地址29不是4的整數倍,因此我們需要再添加3個字節,即將該成員從地址32放置。

第五個成員(short e):由于short類型占用2個字節,因此地址36恰好是2的整數倍,因此我們可以直接填充它而不填充字節,只需跟隨它即可。

這樣,我們的內存對齊就完成了。但這距成功僅一步之遙,這是什么?是的,它是填寫整個結構,然后我們將填寫整個結構。因此,讓我們先回顧一下補碼的原理:“以4字節對齊為例,以結構中最大成員類型的倍數為例,如果超過4個字節,則全部基于4字節的整數倍對齊?!苯Y構中最大的類型是雙精度類型(占用8個字節),并且由于8個字節大于4個字節,因此我們仍然使用4個字節作為基線。整個結構的結束地址是38,而地址38不是4的整數倍,因此我們需要添加額外的2個字節來填充結構。下圖中的紅色是填充的空間:

內存地址圖

到目前為止,我們的內存對齊和填充已完成!接下來,我們用實驗來證明事實,過程如下:

#include 
#include 
 
// 由于VS2010默認是8字節對齊,我們
// 通過預編譯來通知編譯器我們以4字節對齊
#pragma pack(4)
 
// 用于測試的結構體
typedef struct MemAlign
{
    char a[18];    // 18 bytes
    double b;    // 08 bytes    
    char c;        // 01 bytes
    int d;        // 04 bytes
    short e;    // 02 bytes
}MemAlign;
 
int main()
{
    // 定義一個結構體變量
    MemAlign m;
    // 定義個以指向結構體指針
    MemAlign *p = &m;
    // 依次對各個成員進行填充,這樣我們可以
    // 動態觀察內存變化情況
    memset( &m.a, 0x11, sizeof(m.a) );
    memset( &m.b, 0x22, sizeof(m.b) );
    memset( &m.c, 0x33, sizeof(m.c) );
    memset( &m.d, 0x44, sizeof(m.d) );
    memset( &m.e, 0x55, sizeof(m.e) );
    // 由于有補齊原因,所以我們需要對整個
    // 結構體進行填充,補齊對齊剩下的字節
    // 以便我們可以觀察到變化
    memset( &m, 0x66, sizeof(m) );
    // 輸出結構體大小
    printf( "sizeof(MemAlign) = %d", sizeof(m) );
}

在程序運行期間,按以下方式檢查內存:

內存地址圖

其中,以各種顏色表示的下劃線表示每個成員變量,藍色框表示在內存對齊期間填充的多余字節。由于此處看不到填充效果,因此請看下圖?;@子所包圍的字節是與上圖交叉處之外的部分,是填充的字節。

內存地址圖

最后,我要說的是補語的作用。補碼實際上是使此結構定義的數組變量也滿足數組內部的內存對齊要求,以便更好地理解這一點。 ,我制作了一張圖片以與本示例進行比較:

內存地址圖

參考鏈接:


本文來自電腦雜談,轉載請注明本文網址:
http://www.cvs5.com/a/shoujiruanjian/article-364162-1.html

    相關閱讀
    發表評論  請自覺遵守互聯網相關的政策法規,嚴禁發布、暴力、反動的言論

    熱點圖片
    拼命載入中...
    岛国动作片AV在线网站_亚洲精品欧美综合一区二区_2021年最新无码福利视频