整數邊界對齊方式 帶你深入理解記憶體對齊最底層原理

2021-10-14 13:25:14 字數 1467 閱讀 7062

相信絕大多數的人都了解記憶體對齊,對齊後效能高。但是其最最底層的原理是啥呢? 有的人可能會說,因為快取記憶體的工作機制。讀者你很聰明,這是原因之一。但我今天想挖的是更底層一點的原理,讓我們去記憶體的物理構成裡找找答案!

圖1 記憶體外形圖

乙個記憶體是由若干個黑色的記憶體顆粒構成的。每乙個記憶體顆粒叫做乙個chip。每個chip內部,是由8個bank組成的。其構造如下圖:

圖2 chip內部構成

而每乙個bank是乙個二維平面上的矩陣,前面文章中我們說到過。矩陣中每乙個元素中都是儲存了1個位元組,也就是8個bit。

圖3 bank內部構成

那麼對於我們在應用程式中記憶體中位址連續的8個位元組,例如0x0000-0x0007,是從位於bank上的呢?直觀感覺,應該是在第乙個bank上嗎? 其實不是的,程式設計師視角看起來連續的位址0x0000-0x0007,實際上位8個bank中的,每乙個bank只儲存了乙個位元組。在物理上,他們並不連續。下圖很好地闡述了實際情況。

圖4 連續8位元組在記憶體中實際分布

你可能想知道這是為什麼,原因是電路工作效率。記憶體中的8個bank是可以並行工作的。 如果你想讀取址0x0000-0x0007,每個bank工作一次,拼起來就是你要的資料,io效率會比較高。但要存在乙個bank裡,那這個bank只能自己幹活。只能序列進行讀取,需要讀8次,這樣速度會慢很多。

所以,記憶體對齊最最底層的原因是記憶體的io是以8個位元組64bit為單位進行的。對於64位資料寬度的記憶體,假如cpu也是64位的cpu(現在的計算機基本都是這樣的),每次記憶體io獲取資料都是從同行同列的8個chip中各自讀取乙個位元組拼起來的。從記憶體的0位址開始,0-7位元組的資料可以一次io讀取出來,8-15位元組的資料也可以一次讀取出來。

換個例子,假如你指定要獲取的是0x0001-0x0008,也是8位元組,但是不是0開頭的,記憶體需要怎麼工作呢?沒有好辦法,記憶體只好先工作一次把0x0000-0x0007取出來,然後再把0x0008-0x0015取出來,把兩次的結果都返回給你。 cpu和記憶體io的硬體限制導致沒辦法一次跨在兩個資料寬度中間進行io。這樣你的應用程式就會變慢,算是計算機因為你不懂記憶體對齊而給你的一點點懲罰。

擴充套件2:其實在記憶體硬體層上,還有作業系統層。作業系統還管理了cpu的一級、二級、**快取。不知道你有沒有印象,我們前面的文章說過快取記憶體裡的cache line也是64位元組,它是記憶體io的整數倍,不會讓記憶體io浪費。

提取碼:4uqa

整數邊界對齊方式 c中結構體邊界對齊

原則1 普通資料成員對齊規則 第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小的整數倍開始 比如int在32位機為 位元組,則要從4的整數倍位址開始儲存 原則2 結構體成員對齊規則 如果乙個結構裡有某些結構體成員,則該結構體成員要從其內部最大元素大小的整數倍位址...

整數邊界對齊方式 C高階 記憶體對齊

碼字不易,對你有幫助點讚 關注支援一下作者不會程式設計的程式圓看更多乾貨,獲取第一時間更新如果想看比較好看的排版,可以閱讀原文 c高階 四 記憶體對齊 mp.weixin.qq.com 我們這一節主要來講一相關的些比較重要的知識。struct s1 上面是乙個結構體,也是我們自定義的一種型別。我們知...

指標從0 1帶你深入理解

好的指標,一定要圍繞業務模式打造 通速的來講,指標就是用來衡量某某事物的值,體系就是很多個衡量事物的值湊成的乙個有相互性,有層次性的值 建立業務量化衡量的標準 減少重複性工作,提高分析效率 可以快速定位問題 當公司新出乙個業務的時候,需要通過資料更加客觀,明確的的了解到業務的發展趨勢,發展是否健康,...