一看就懂的記憶體對齊

2021-10-17 23:24:01 字數 1309 閱讀 7903

記憶體對齊對於程式設計師來說透明的,這是編譯器該做的事,將每個資料按排到合適的位置,這也是編譯器優化的結果。所以了解記憶體對齊的原理對於乙個程式設計師寫**是十分必要的,就不會導致大量的記憶體碎片產生。

1、對於結構體的第乙個成員,將它在整個結構體在記憶體中分布的偏移量看成0,以後的每乙個資料成員的偏移量必須是 min 的倍數。

2、每個資料成員完成在結構體內部對齊的時候,還要進行整個結構體在記憶體中的對齊,整個結構體的大小為 min 的倍數。

#pragram pack(n) 表示的是設定n位元組對齊,在vc6中預設是8,所以,我們一般都不用考慮這個,除非我們自己自定義記憶體對齊。

struct a

;struct b

;

對於結構體 a

a的長度為1位元組,偏移量為0;b的長度為2,它的偏移量應該是2的倍數,之前加起來的資料大小總和為1位元組,所以a後面要有一位元組的空;c的長度為4位元組,偏移量應該是4的倍數,之前的資料大小總和為1+1+2=4位元組,剛好是4的倍數,在結構體內部的大小總和為8。再進行結構體的對齊,結構體資料長度最大是4,要是4的倍數,8剛好就是4的倍數,所以結果為8。

對於結構體b

b的長度為2位元組,偏移量為0;c的長度為4,它的偏移量應該是4的倍數,之前加起來的資料大小總和為2位元組,所以b後面要有2位元組的空位;a的長度為1位元組,偏移量應該是1的倍數,之前的資料大小總和為2+2+4=8位元組,是1的倍數,在結構體內部的大小總和為9。再進行結構體的對齊,結構體資料長度最大是4,要是4的倍數,但9不是4的倍數,所以結果為12。

一、硬體原因:加快cpu訪問的速度

我們大多數人在沒有搞清楚cpu是如何讀取資料的時候,基本都會認為cpu是一位元組一位元組讀取的,但實際上它是按照塊來讀取的,塊的大小可以為2,4,8,16。塊的大小也稱為記憶體讀取粒度。

假設cpu沒有記憶體對齊,要讀取乙個4位元組的資料到乙個暫存器中,(假設讀取粒度為4),則會出現兩種情況

1、資料的開始在cpu讀取的0位元組處,這剛cpu一次就你能夠讀取完畢

2、資料的開始沒在0位元組處,假設在1位元組處吧,cpu要先將03位元組讀取出來,在讀取47位元組的內容。然後將03位元組裡的0位元組丟棄,將47位元組裡的5,6,7位元組的資料丟棄。然後組合1,2,3,4的資料。

由此可以看出,cpu讀取的效率不是很高,可以說比較繁瑣。

但如果有記憶體對齊的話:

由於每乙個資料都是對齊好的,cpu可以一次就能夠將資料讀取完成,雖然會有一些記憶體碎片,但從整個記憶體的大小來說,都不算什麼,可以說是用空間換取時間的做法。

二、平台原因:

不是所有的硬體平台都可以訪問任意位址上的任意資料,某些硬體平台只能在某些位址處取某些型別的資料,否則丟擲硬體異常。

一看就懂的SwitchHosts

switchhosts 是乙個管理 切換多個 hosts 方案的工具。它是乙個免費開源軟體。日常開發工作中,我們可能經常需要切換各種 hosts 繫結,比如在本地開發時可能需要乙個開發環境的 hosts 繫結方案,發布到測試環境後又有乙個測試環境的 hosts 繫結方案,然後可能還有乙個預發布環境,...

一看就懂TCP 連線

我們先來看乙個定義。這樣理解比較抽象。我們換個角度。它的本質還是傳輸控制。如果讓我們自己設計這個傳輸,我們會怎麼想呢。tcp 協議它會先建立連線。三次握手目的是保證雙方都有傳送和接收的能力 首要原因是為了防止舊的重複連線初始化造成混亂。同步雙方初始序列號客戶端和服務端都處於 closed 狀態。先是...

資訊熵 一看就懂

先給出資訊熵的公式 首先了解一下資訊量 資訊量是對資訊的度量,就跟時間的度量是秒一樣,當我們考慮乙個離散的隨機變數 x 的時候,當我們觀察到的這個變數的乙個具體值的時候,我們接收到了多少資訊呢?多少資訊用資訊量來衡量,我們接受到的資訊量跟具體發生的事件有關。資訊的大小跟隨機事件的概率有關。越小概率的...