1. 程式人生 > >記憶體系列二:深入理解硬體原理

記憶體系列二:深入理解硬體原理

本篇文章承接上文繼續介紹DDR記憶體的硬體原理,包括如何定址,時序和時延以及可以為提高記憶體的效能可以有哪些方法。

上次雖然解決了小張的問題,卻引發了他對記憶體原理的興趣。這不他又來找我了,說我還欠他一個解釋。這次我們約在一個咖啡館見面,這次內容有點深入,我帶了些圖片,小張也點了一大杯美式,計劃大幹一場。看著他認真的樣子,我也決定毀人不倦,把他也帶入IT工程師的不歸路。。。

定址(addressing)

為了瞭解前幾天說的幾個延遲引數,不得不介紹下DIMM的定址方式。也許你發現了上次介紹Rank和chip的關係時,有個Bank/Column/row我們沒有講到,它們和如何定址密切相關。還記得上次的圖片嗎?

 

 

這次我們來看看rank和Chip裡面有什麼,如下圖:

 

 

這是個DDR3一個Rank的示意圖。2GB的記憶體共有16個chip,每個chip容量為128MB。我們把左邊128MB Chip拆開來看,它是由8個Bank組成,每個Bank核心是個一個儲存矩陣,就像一個大方格子陣。這個格子陣有很多列(Column)和很多行(Row),這樣我們想存取某個格子,只需要告知是哪一行哪一列就行了,這也是為什麼記憶體可以隨機存取而硬碟等則是按塊存取的原因。

XXXX,CAS#和RAS#只有一根訊號線。實際上每個格子的儲存寬度是記憶體顆粒(Chip)的位寬,在這裡由8個Chip組成一個Rank,而CPU定址寬度是64bit,所以64/8=8bit,即每個格子是1個位元組。16384rows*1024columns*8bank=128MB。每一個格子都是由一個電晶體和一個電容組成。

對於DDR3,我們通常說它是8n-prefetch(這兒n是指每個rank的bank數目),因為DDR3,每個IC有8個bank,每個bank讀取資料的最小單位是8bit,一個byte。每次資料讀取request,都會讀取8*8bit=64bitdata,而不管這些資料是否都是我們所需要的,比如我們只需要其中的某個byte,但讀request會讀取8個byte。

選擇每個格子也不是簡單的兩組訊號,是由一系列訊號組成,以這個2GB DDR3為例:

1. 片選(Chip Select)訊號,S0#和S1#,每個用於選擇是哪個Rank。

2. Bank地址線,BA0-BA2, 2^3=8,可以選擇8個Bank

3. 列選 (Column Address Select), CAS#,用於指示現在要選通列地址。

4. 行選(Row Address Select),RAS#用於指示現在要選通行地址。

5. 地址線,A0-A13,用於行和列的地址選擇(可並不都用於地址,本處忽略)。

6. 資料線,DQ0-DQ63,用於提供全64bit的資料。

7. 命令,COMMAND,用於傳輸命令,如讀或者寫等等。

注意這裡沒有記憶體顆粒的選擇訊號線,只有Rank的選擇訊號。在Rank選擇好後,8個記憶體顆粒一起被選中,共提供64bit的資料。

讀取和寫入資料也稍微複雜點,簡單來說分為以下三步:

1. 行有效。RAS#低電平,CAS#高電平。意味著現在行地址有效,同時在A0-A13傳送地址訊號,即2^13個Row可以選擇。

2. 列有效。RAS#高電平,CAS#低電平。意味著列地址有效,這時在A0-A13上傳送的是列地址。沒錯,A0-A13是行列共用的,所以每個格子選擇需要有1和2兩步才能唯一確定。

3. 資料讀出或寫入。根據COMMAND進行讀取或者寫入。在選定好小方格後,就已經確定了具體的儲存單元,剩下的事情就是資料通過資料I/O通道(DQ)輸出到記憶體總線上了。

這裡只介紹隨機訪問, Burst模式這裡略過。下圖是個簡單的圖示:

 

 

時序(Timing)

一氣說了這麼多,我不禁口乾舌燥,停下來喝了一大口咖啡。小張以為我說完了,著急的問我:“我好像聽懂了,不過那好幾個數字還沒講呢。”。彆著急啊,且聽我慢慢道來。正因為訪問一個數據需要大致三步,為了保證訊號的完整性,步驟直接要有區隔,一起發出來會造成錯亂,間隔太近也會為取樣帶來難度,容易引入噪音。所以時序非常重要,

下面是個背對背(back-to-back)讀寫的時序圖:

 

時延(Latency)

小張一看到這個圖,不禁大叫:”太複雜了,看得我都犯密集恐懼症了,看不懂!“。沒關係,我們拆開了一個個看。

1. CL: CAS Latency。CL是指CAS發出之後,仍要經過一定的時間才能有資料輸出,從CAS與讀取命令發出到第一筆資料輸出的這段時間,被定義為CL(CAS Latency,CAS時延)。由於CL只在讀取時出現,所以CL又被稱為讀取時延(RL,Read Latency)。也就是我們上面第3步讀取時需要的時間。CL是延遲裡面最重要的引數,有時會單獨在記憶體標籤上標出如CLx。它告訴我們多少個時鐘週期後我們才能拿到資料,CL7的記憶體會延遲7個週期才能給我們資料,CL9的則要等9個。所以越小我們越能更快的拿到資料。注意這裡的週期是真正的週期而不是標註的DDR3 1333MHz的週期,因為一個週期傳輸兩次,真正的週期只是1/2,這裡是666MHz。如下圖,是CL7和CL9的例子:

 

 

如果相同頻率的記憶體,CL7可以比CL9有22%的效能提高。

2. tRCD:RAS到CAS時延。在傳送列讀寫命令時必須要與行有效命令有一個間隔,這是根據晶片儲存陣列電子元件響應時間所制定的延遲。即步驟1和2要間隔的時間。這個間隔當然也是越快越好了,下面是個tRCD=3的例子:

 

 

你也可以看出這個時間也是啟用命令和讀命令的間隔。

3. tRP: 預充電有效週期(Precharge command Period)。在上一次傳輸完成後到下一次行啟用前有個預充電過程,要經過一段充電時間才能允許傳送RAS。也就是步驟1的準備工作要做多久。下面是個例子:

 

 

還有兩個類似的時延tRAS和CMD,我看到小張都快睡著了就不講了。總之,所有這些時延共同構成了整體時延,而時延是越小越好。

SPD

說了這麼多,小張總算搞懂記憶體標籤條上的4-4-4-8, 5-5-5-15, 所代表的 CL-tRCD-tRP-tRAS-CMD都是啥意思了。不過小張有點搞不懂,這些資料印在紙上消費者是看懂了(實際上似乎沒多少人瞭解),可電腦又沒長眼睛,它是怎麼知道的呢?其實,每個DIMM在板子上都有塊小的儲存晶片(EEPROM),上面詳細記錄了包括這些的很多引數,還有生產廠家的程式碼等等,這也是BIOS為什麼能知道我們插了哪種記憶體的原因。在小張的記憶體條上,我指給了他看:

 

 

實際上隨著DDR的一步步進化,這些延遲的時鐘週期個數也在步步提高,但由於頻率的加快,實際上是在時間是在慢慢的減少的。

效能提高的其他手段

看時間還早,我和小張聊起了除了提高頻率,還有什麼辦法能夠提高記憶體存取速度。

1。多通道(Channel)

現代記憶體控制器都從北橋移入CPU內部,而且記憶體控制器都可以同時操作多個通道。典型的桌上型電腦和筆記本CPU很早就支援雙通道,現在還加入了三通道。如果資料分佈在插在不同的通道上的記憶體條上,記憶體控制器可以不管上面這些延遲啊時序啊,同時可以讀取他們,速度可以翻倍甚至三倍!小張聽了跳了起來:”我也要翻倍!”。別急,要啟用多通道,首先要插對插槽。現在主機板製造商為了讓小白使用者插對記憶體條,通常用顏色標識記憶體通道。注意同一個通道顏色不同!所以要把記憶體插在顏色相同的記憶體插槽裡,才能讓記憶體佔據不同的通道。最好有主機板手冊檢查一下,插好後進入BIOS裡面看看現在記憶體狀態是不是多通道模式。

2。Interleave

看著小張躍躍欲試的樣子,我不禁給他潑了盆冷水。幻想美妙,現實殘酷。多通道在很多時候用處並不明顯!因為程式的區域性性,一個程式並不會把資料放到各個地方,從而落入另一個DIMM裡,往往程式和資料都在一個DIMM裡,加上CPU的Cache本身就會把資料幫你預取出來,這個提高就個不明顯了。除非你執行很多巨型任務才行。

“啊,我都是開一個遊戲打,對我來說沒啥用處啊,簡直是雞肋!”,小張說。也不盡然,還有種辦法,就是讓同一塊記憶體分佈到不同的通道中去,這種技術叫做Interleaving。這樣無論Cache命中與否都可以同時存取,多通道的技術才能發揮更大的用處。“太好了,要怎麼才能開啟這個interleave呢?”,我不禁呵呵了,這個功能一般只有伺服器CPU才有,你的i5要是有了,誰去買幾千上萬的伺服器CPU呢?

3。Overclock

“你這不是廢話嗎,我要怎麼樣才能搭建個發燒機才配有的高速記憶體呢?”。其實小張可以購買發燒級的記憶體條。這些記憶體條DDR3標註達到2133以上!但是要注意,如果我們把這些記憶體插入一般主機板,很有可能會執行在1333或者1600上面,因為這是DDR3規定的最高頻率。好馬配好鞍,要有個能支援超頻記憶體的主機板,在主機板BIOS裡面升壓升頻才能真正用好這些發燒記憶體條。

尾聲

時間差不多了,我向小張保證下次還會介紹神祕的BIOS如何初始化記憶體,正要離去。小張拉住了我,說:“你上次挖的坑還沒填呢!”“什麼坑?”也許是我挖坑太多,記不住了。“就是上次你讓我回去想的三個問題。第一個我知道了,DIMM有防呆口,幾代DDR防呆口位置不同,插不進去,我在網上google過了,後面兩個實在想不出來”。好吧,那我們長話短說,實際上兩個問題可以一起回答,今天我們知道DDR每代的各種時延引數是上升的,所以如果兩代一樣的頻率,實際上效能有可能還會下降!譬如DDR2 800在很多時候比DDR3 800的時延要小。我們可以認為每代的起點比前一代的低,有一段重合期,在頻率上去後會彌補時延的時鐘個數差異,比較時延是clock個數,而不是時間,clock快了,有可能時延會更小。而這段重合期,也為不同的商業策略留下了空間。

小張還是抓住我,他不知道從哪裡查了些名詞,什麼預取個數每代增加,而核心頻率不同於外部頻率等等。我希望他能自己找找資料看看,也順便挖了個新坑:

1. 為什麼每代DDR要升級,不直接把頻率向上提高就行了,為什麼沒有DDR2 3200的記憶體?

2. DDR的記憶體還是並行的資料,序列似乎可以更高速,比格更高,為什麼不弄個序列訪問的記憶體呢?

小張陷入了沉思,我也暗喜又騙到一頓咖啡下午茶。不過回去還要準備些材料才能繼續混吃混喝,下次介紹完記憶體的BIOS部分,還有啥題目可以繼續吸引小張呢?