目錄
記憶體對齊的原因
記憶體對齊的原理
1.平台原因(移植原因):
不是所有的硬體平台都能通路任意位址上的任意資料的;某些硬體平台隻能在某些位址處取某些特定類型的資料,否則抛出硬體異常。
2.性能原因:
記憶體對齊最最底層的原因是記憶體的IO是以64bit為機關進行的,是以記憶體對齊為了高效的記憶體IO,大部分都是更為高效的高速緩存IO。
資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在于,為了通路未對齊的記憶體,處理器需要作兩次記憶體通路;而對齊的記憶體通路僅需要一次通路。你int如果從0位址開始就一次讀取就夠了,如果你從1位址開始,那麼要讀2次。
前面我們說過記憶體是由chip構成。每個chip内部,是由8個bank組成的。其構造如下圖:
圖2.記憶體顆粒實體結構
在每個bank内部,就是電容的行列矩陣結構了。(注意,二維矩陣中的一個元素一般存儲着8個bit,也就是說包含了8個小電容)。
圖3.bank實體結構
8個同位置的元素,一起組成在記憶體中連續的64個bit。如下圖
圖4.jpg
記憶體在進行IO的時候,一次操作取的就是64個bit。
是以,記憶體對齊最最底層的原因是記憶體的IO是以64bit為機關進行的。 對于64位資料寬度的記憶體,假如cpu也是64位的cpu(現在的計算機基本都是這樣的),每次記憶體IO擷取資料都是從同行同列的8個chip中各自讀取一個位元組拼起來的。從記憶體的0位址開始,0-63bit的資料可以一次IO讀取出來,64-127bit的資料也可以一次讀取出來。CPU和記憶體IO的硬體限制導緻沒辦法一次跨在兩個資料寬度中間進行IO。
假如對于一個c的程式員,如果把一個bigint(64位)位址寫到的0x0001開始,而不是0x0000開始,那麼資料并沒有存在同一行列位址上。是以cpu必須得讓記憶體工作兩次才能取到完整的資料。效率自然就很低。這下你有沒有徹底了解了記憶體對齊?
擴充1:如果不強制對位址進行操作,僅僅隻是簡單用c定義一個結構體,編譯和連結器會自動替開發者對齊記憶體的。盡量幫你保證一個變量不跨列尋址。 擴充2:其實在記憶體硬體層上,還有作業系統層。作業系統還管理了CPU的一級、二級、三級緩存。實際中不一定每次IO都從記憶體出,如果你的資料局部性足夠好,那麼很有可能隻需要少量的記憶體IO,大部分都是更為高效的高速緩存IO。但是高速緩存和記憶體一樣,也是要考慮對齊的。