內存對齊問題的一些總結

要了解爲什麼要內存對齊,首先我們要了解什麼是內存對齊

什麼是內存對齊 
關於什麼是內存對齊,我們先來看幾個例子

typedef struct {
    int a;
    double b;
    short c;
}A;
typedef struct {
    int a;
    short b;
    double c;
}B;

分別對他們求大小,sizeof(A),sizeof(B)我們所得到的結果是不同的, 
sizeof(A)=24而sizeof(B)=16爲什麼會產生不一樣的結果呢? 
這是非常簡單的一個例子,體現了結構體的內存對齊規則。 
在結構體中,從結構體的首地址開始,假設地址從0開始。 
對結構體A來說,a佔4個字節,佔從0~3的字節,b是double類型佔8個字節,佔從8~15的字節,c佔兩個字節,從16~17的字節。 
對結構體B來說,a佔4個字節,從0~3,b佔兩個字節從4~6;c佔8個字節從8~15。 
這就是內存對齊,對齊規則是按照成員的聲明順序,依次安排內存,其偏移量爲成員大小的整數倍,0看做任何成員的整數倍,最後結構體的大小爲最大成員的整數倍(所以這裏的A的大小是24,而不是18)。

C語言和C++中空類和空結構體的大小 
在C++中規定了空結構體和空類的內存所佔大小爲1字節,因爲c++中規定,任何不同的對象不能擁有相同的內存地址(編譯器自動增加空類和空結構體一個指針來進行區分)。 
而在C語言中,空的結構體在內存中所佔大小爲0。(gcc中測試爲0,其他編譯器不一定)

爲什麼要內存對齊? 
1.平臺原因(移植原因):不是所有的硬件平臺都能訪問任意地址上的任意數據的;某些硬件平臺只能在某些地址處取某些特定類型的數據,否則拋出硬件異常。 
2.性能原因(硬件原因):cpu把內存當成是一塊一塊的,塊的大小可以是2,4,8,16 個字節,因此CPU在讀取內存的時候是一塊一塊進行讀取的,塊的大小稱爲(memory granularity)內存讀取粒度。

我們再來看看爲什麼內存不對齊會影響讀取速度?

    假設CPU要讀取一個4字節大小的數據到寄存器中(假設內存讀取粒度是4),分兩種情況討論:

           1.數據從0字節開始

        2.數據從1字節開始

解析:當數據從0字節開始的時候,直接將0-3四個字節完全讀取到寄存器,結算完成了。

        當數據從1字節開始的時候,問題很複雜,首先先將前4個字節讀到寄存器,並再次讀取4-7字節的數據進寄存器,接着把0字節,4,6,7字節的數據剔除,最後合併1,2,3,4字節的數據進寄存器,對一個內存未對齊的寄存器進行了這麼多額外操作,大大降低了CPU的性能。

     但是這還屬於樂觀情況,上文提到內存對齊的作用之一是平臺的移植原因,因爲只有部分CPU肯幹,其他部分CPU遇到未對齊邊界就直接罷工了。

轉自: 爲什麼要進行內存對齊以及對齊規則

           什麼是內存對齊?爲什麼要內存對齊?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章