帶你深刻理解內存對齊最底層原理

相信絕大多數的人都瞭解內存對齊,對齊後性能高。 可是其最最底層的原理是啥呢?  有的人可能會說,由於高速緩存的工做機制。 讀者你很聰明,這是緣由之一。 但我今天想挖的是更底層一點的原理,讓咱們去內存的物理構成裏找找答案!

內存物理結構

咱們來了解一下內存的物理構造,通常內存的外形圖片以下圖:程序員

圖片

圖1 內存外形圖緩存

一個內存是由若干個黑色的內存顆粒構成的。每個內存顆粒叫作一個chip。每一個chip內部,是由8個bank組成的。其構造以下圖:ide

圖片

圖2 chip內部構成性能

而每個bank是一個二維平面上的矩陣,前面文章中咱們說到過。矩陣中每個元素中都是保存了1個字節,也就是8個bit。spa

圖片

圖3 bank內部構成操作系統

內存編址方式

那麼對於咱們在應用程序中內存中地址連續的8個字節,例如0x0000-0x0007,是從位於bank上的呢?直觀感受,應該是在第一個bank上嗎?其實不是的,程序員視角看起來連續的地址0x0000-0x0007,其實是位於8個bank中的,每個bank只保存了一個字節。在物理上,他們並不連續。下圖很好地闡述了實際狀況。orm

圖4 連續8字節在內存中實際分佈blog

你可能想知道這是爲何,緣由是電路工做效率。內存中的8個bank是能夠並行工做的。若是你想讀取地址0x0000-0x0007,每一個bank工做一次,拼起來就是你要的數據,IO效率會比較高。但要存在一個bank裏,那這個bank只能本身幹活。只能串行進行讀取,須要讀8次,這樣速度會慢不少。圖片

結論

因此,內存對齊最最底層的緣由是內存的IO是以8個字節64bit爲單位進行的。 對於64位數據寬度的內存,假如cpu也是64位的cpu(如今的計算機基本都是這樣的),每次內存IO獲取數據都是從同行同列的8個bank中各自讀取一個字節拼起來的。從內存的0地址開始,0-7字節的數據能夠一次IO讀取出來,8-15字節的數據也能夠一次讀取出來。ip

換個例子,假如你指定要獲取的是0x0001-0x0008,也是8字節,可是不是0開頭的,內存須要怎麼工做呢?沒有好辦法,內存只好先工做一次把0x0000-0x0007取出來,而後再把0x0008-0x0015取出來,把兩次的結果都返回給你。CPU和內存IO的硬件限制致使沒辦法一次跨在兩個數據寬度中間進行IO。這樣你的應用程序就會變慢,算是計算機由於你不懂內存對齊而給你的一點點懲罰。

擴展1:事實上,編譯和連接器會自動替開發者對齊內存的,儘可能幫你保證一個變量不跨列尋址。可是他不能作到十分完美。

擴展2:其實在內存硬件層上,還有操做系統層。操做系統還管理了CPU的一級、二級、三級緩存。不知道你有沒有印象,咱們前面的文章說太高速緩存裏的Cache Line是64字節,它是內存IO單位的8倍,不會讓內存IO浪費。

相關文章
相關標籤/搜索