1, 簡介
DDR SDRAM(Double Data Rate Synchronous Dynamic Random Access Memory,雙數據率同步動態隨機存儲器)通常被我們稱為DDR,其中的“同步”是指內存工作需要同步時鐘,內部命令的發送與數據傳輸都以它為基準。DDR是一種掉電就丟失數據的存儲器件,并且需要定時的刷新來保持數據的完整性。
DDR是我們嵌入式系統使用比較多的硬件,但是平時我們在做軟件開發或者優化的時候,對它的組成及工作原理了解卻很少。主要原因是對于DDR的軟件開發主要是配置參數,而這些參數由芯片廠商已經提供好了。其實,要想對系統做深度的功耗優化和性能優化,是很有必要深挖DDR的組成與工作原理的細節。
現在嵌入式系統設計或者計算機設計,考慮到存儲性能、存儲容量、成本等因素,通常采用存儲金字塔式的設計,比如CPU后面緊接著寄存器,寄存器后面跟著cache,cache后面緊接著DDR,然后DDR后面跟著SSD、EMMC等非易失。通過利用程序的時間及空間局部性原理,可以在盡可能少的影響性能的前提下,增加存儲容量,降低存儲成本。
隨著CPU 發展,內存也發生了巨大的變革,DDR從誕生到現在已經經歷了多代,分別是第一代SDR SDRAM(Single Data Rate SDRAM,同步型動態存儲器),第二代的DDR SDRAM,第三代的DDR2 SDRAM,第四代的DDR3 SDRAM,現在已經發展到DDR5 SDRAM。為了實現容量增加和傳輸效能增加,規范的工作電壓越來越低,DDR容量越來越大,IO的速度越來越高。
歷代ddr特性對比
Voltage(VDDQ):存儲芯片的輸出緩沖供電電壓。
Device Width:顆粒位寬,常見為4/8/16bit。一個Memory Array中由行地址和列地址的交叉選中一個位,若2個Array疊加在一起,就同時選中了2個Bit,位寬是X2。若4個Array疊加到一起,就能夠同時選中4個Bit,位寬則是X4。也就是說,對一個X4位寬的DDR 顆粒,如果給出行地址和列地址,就會同時輸出4個Bit到DQ(數據輸入、輸出:雙向數據總線)數據線上。
Die Density:顆粒密度,也就是容量,隨著DDR迭代,容量越來越大。
Data rates:MT/s指每秒傳輸多少個數據(Mega-transfer per second),和時鐘頻率是兩個不同的概念。DDR(dual data rate)是雙邊沿傳輸數據。因此MT/s是IO時鐘頻率的兩倍。
Prefetch:在一個時鐘周期中,同時將相鄰列地址的數據一起取出來,并行取出DRAM數據,再由列地址0/1/2(DDR1使用列0,DDR2使用列0和列1,DDR3/DDR4使用列0,1和2)選擇輸出。2n/4n/8n。這里的數字指的就是并行取出的位數。這里的n,就是DQ位寬,即上面的device width(x4/x8/x16)。所以DDR3 16bit SDRAM內存顆粒,16bit指的是位寬,其一次讀寫訪問的數據量是8*16=128bit
Bank:DDR4以前是沒有Bank Group的,所以該值就表示整個顆粒中Bank數量。但是在DDR4和DDR5中,就表示每個Bank Group中Bank的數量,整個顆粒Bank數量 = Bank Group * Bank。
Bank Group:Bank分組數量,該特性只存在于DDR4和DDR5中。
Burst Length:指突發長度,突發是指在同一行中相鄰的存儲單元連續進行數據傳輸的方式,連續傳輸所涉及到存儲單元(列)的數量就是突發長度,在DDR SDRAM中指連續傳輸的周期數。 一般對應預取bit數目。
Core frequency:顆粒核心頻率,即內存cell陣列的工作頻率,它讀取數據到IO Buffer的頻率。 它是內存頻率的基礎,其他頻率都是在該頻率的基礎上得出來的。
IO clk Frequency:內存的數據傳輸速率。 它和內存的prefetch有關。 對于DDR,一個時鐘周期的上升沿和下降沿都在傳輸數據,即一個時鐘周期傳輸2bit的數據,所以DDR的prefetch為2bit。 對于DDR2,IO時鐘頻率是其核心頻率的兩倍,同時也是雙沿傳輸數據,因此DDR2的prefetch為2×2bit=4bit。 對于DDR3,IO時鐘頻率是其核心頻率的四倍,同時也是雙沿傳輸數據,因此DDR3的prefetch為4×2bit=8bit。
DDR SDRAM是由威盛等公司提出的第二代SDRAM標準,主要它允許在時鐘脈沖的上升沿和下降沿都能傳輸數據,這樣不需要提高時鐘頻率就能實現雙倍的SDRAM提速。 DDR2 SDRAM是由電子設備工程聯合委員會開的第三代SDRAM內存技術標準,相比上一代提供了更高運行效能(擁有兩倍與上一代的預讀取能力,4bit數據prefetch)和更低的電壓(1.8v)。 DDR3 SDRAM相比上一代,電壓更低(1.5v),效能更高(支持8bit prefetch),只需133MHz就能實現1066MHz的總線頻率。 DDR4相比上一代,工作電壓更低(1.2v),效能更高(16bit prefetch),同樣的頻率下,理論速度是上一代的兩倍。
2, 框架
DDR子系統框圖
DDR SDRAM子系統包含DDR controller、DDR PHY和DRAM存儲顆粒三部分。我們分別看一下各部分的組成,然后講述一下數據的讀寫過程。
2.1 DDR控制器
內存控制器負責初始化DRAM,并重排讀寫命令,以獲得最大的DRAM帶寬。它通過多端口與其他用戶核進行連接,這些端口的類型包含AXI4/AXI3/AHB/CHI。每個端口有可配置的寬度、命令和數據FIFO。
內存控制器接收來自于一個或者多個CPU、DSP、GPU的請求,這些請求使用的地址是邏輯地址,由仲裁器來決定這些請求的優先級,并將其放入內存控制器中。如果一個請求處于高優先級(贏得仲裁),會被映射到一個DRAM的物理地址并被轉換為一個DRAM命令序列。這些命令序列被放置在內存控制器中的隊列池(Queue pool)中,內存控制器會執行隊列池中這些被掛起的命令,并將邏輯地址轉化為物理地址,并由狀態機輸出符合DRAM訪問協議的電信號,經由PHY驅動DRAM的物理IO口。
Arbitration CMD priority:仲裁器,仲裁CMD的優先級。 會對來自各端口的請求進行仲裁,并將請求發送給控制器,仲裁其從端口收到的每個事務,每個事務都有一個相對應的優先級。 端口仲裁邏輯會根據優先級進行處理,從而確定如何向控制器發出請求。 以Cadence Denali內存控制器為例,它有幾種仲裁策略:
Round Robin:每個端口對應一個獨立的計數器,當端口上有請求被接受的時候,計數器就會增加,然后仲裁器會針對計數器非0的端口的請求進行輪流仲裁,每仲裁執行一次,相應端口的計數器減一,直到端口接受請求計數器變為0。
帶寬分配/優先級輪流操作:結合輪流操作、優先級、帶寬和端口帶寬保持等,根據用戶分配的命令優先級,將傳入的命令按優先級分組。 在每個優先級組內,仲裁器評估請求的端口、命令隊列和請求的優先級,從而確定優先級。 當控制器繁忙時,超過其帶寬分配的端口,可能會接受較低的優先級服務。
加權優先級循環:是一種面向服務質量的算法,結合了循環操作、優先級、相對優先級、端口排序的功能。 根據命令的優先級或該類型命令的相關端口的優先級,將傳入的命令分成優先級組。 具有較高權重的端口可能會更頻繁的接受仲裁,從而更容易被運行到。
DDR SDRAM Control:DDR SDRAM的控制。 包含了一個命令隊列,接受來自仲裁器的命令。 該命令隊列使用一個重排算法來決定命令的放置順序。 重排邏輯遵循一些規則,通過考慮地址碰撞、源碰撞、數據碰撞、命令類型和優先級,來確定命令插入到命令隊列的位置。 重排邏輯還通過命令分組和bank分割,來提高控制器的效率。 當命令進入命令隊列后,選擇邏輯掃描命令隊列中的命令進行運行。 若較高優先級的命令還沒有準備好運行,較低優先級的命令不與命令隊列中排在前面的命令沖突,那么這個較低優先級的命令,可以先于該沒準備好的高優先級命令運行。 此外,控制器還包含一個仲裁塊,支持軟件可編程接口、外部引腳及計數器的低功耗控制。 另外,控制器支持調頻功能,用戶可以通過操作寄存器組,調整ddr的工作頻率。
Transaction Processing:事務處理用于處理命令隊列中的命令。 該邏輯會重排命令,使DRAM的讀寫帶寬吞吐最大化。
2.2 DDR 物理層
DDR PHY是連接DDR顆粒和DDR Controller的橋梁,它負責把DDR Controller發過來的數據轉換成符合DDR協議的信號,并發送到DDR顆粒。相反地,它也負責把DRAM發送過來的數據轉換成符合DFI(DDR PHY Interface)協議的信號并發送給內存控制器。DDR PHY和內存控制器統稱為DDR IP,他們保證了SoC和DRAM之間的數據傳輸。
目前在DDR IP的市場上,國際廠商占據較高的市場份額,而國內IP企業占比很小,究其原因,主要是由于DDR PHY具有較高的技術門檻,要在這類PHY上實現突破并不容易。DDR PHY是一個系統工程,在如下方面需要著重關注:* DDR PHY的數據傳輸采用并行多位、單端突發的傳輸模式,對電源完整性PI(Power Integrity,電源完整性)和信號完整性SI (Signal Integrity,信號完整性)的要求很高。
為了能夠補償不確定的延時,針對不同信號,DDR PHY有個靈活配置的延時電路及對應的輔助邏輯,這些延時電路可能會隨著電壓及溫度變化而變化。 因此PHY針對這些電路要有校準(Training),可以說DDR PHY是對Training要求最多的接口。
2.3 DDR DRAM顆粒
從DDR PHY到內存顆粒的層次關系如下:channel->DIMM->rank->chip->bank->row/column組成的memory array。例如,i7 CPU 支持兩個Channel(雙通道),每個Channel上可以插2個DIMM(dual inline memory module,雙列直插式存儲模塊),每個DIMM由2個rank構成,8個chip組成一個rank。由于現在多數芯片的位寬是8bit,而CPU的位寬是64bit,因此經常是8個芯片可以組成一個rank。* Channel:簡單理解一個通道對應一個DDR控制器,每個通道擁有一組地址線、控制線和數據線。
DIMM:是主板上的一個內存插槽,一個channel可以包含多個DIMM。
Rank:一組可以被一個內存通道同時訪問的芯片組合稱作一個rank,一個rank中的每個芯片都共用內存通道提供的地址線、控制線和數據線,同時每個芯片都提供一組輸出線,這些輸出線組合起來就是內存條的輸出線。 簡單來說rank是一組內存芯片集合,當芯片位寬芯片數=64bit(內存總位寬)時,這些芯片組成一個Rank,存儲64bit的數據。 一般每個芯片位寬是8bit,然后內存條每面8個芯片,那么每面就構成了一個Rank,這兩面的Rank通過一根地址線來區分當前要訪問的是哪一面。 同一個Rank中所有的芯片協作來讀取一個地址(1個Rank,8個芯片8bit=64bit),這個地址的不同bit,每8個一組分散在這個Rank上的不同芯片上。 設計Rank的原因是為了減少每個芯片的位寬(在CPU總位寬確定的前提下,比如64bit),降低復雜度。
Chip:是內存條上的一個芯片,由多個bank組成,大多數是4bit/8bit/16bit,多個chip做成一個rank,配合完成一次訪問的位寬。
Bank:是一個邏輯上的概念。 一個bank可以分散到多個chip上,一個chip也可以包含多個bank。
Row、Column組成的memory array:可以簡單的理解bank為一個二維bit類型的數組。 每個bank對應一個bit,8個bank組成8bit的數據。
3, DRAM剖析
接下來深入的剖析一下DRAM的組成及工作原理。對于DRAM的原理,看到一篇很不錯的文章《深入內存/主存:解剖DRAM存儲器 - 知乎 (zhihu.com)》,以下內容基本上來自于這篇文章。
3.1 基本結構
1)DRAM的基本單元
基本的DRAM單元(cell),是一個電容加一個CMOS晶體管組成的電路。通過給晶體管最上面的一端(稱作柵極)加上電壓或是取消電壓,就可以控制CMOS晶體管的開、關。一旦打開就可以讀出電容上存儲的電量,或者向電容寫入電量。這樣電容上的電荷有無就對應著存儲1bit的1或0。
內存單元
為了存儲更多的bit,可以用如上的DRAM單元組成存儲陣列。行對應的是word line,即字線。列對應的是bit line,即位線。當某一行的字線上通電后,這一行的cell上的電容就會經過位線進行充放電。通過讀取位線上的電壓變化,就能判斷存儲的是0,還是1。由于電容很小,打開字線后產生的電壓波動也很小,所以在讀取的時候,要經過sense amplifier進行放大。
每個位線都接在一個放大器上,由于每個cell的電容太小了,在讀某一bit前,先對bit line進行precharge。預充的電壓為工作電壓的一半。這樣在打開字線后,位線上的輕微變化也能被放大器捕捉到,并在本地還原、暫存字線對應整行cell的電壓。其實,當讀了位線(電容放電)后,電容上的電荷就會發生了改變,這是一種破壞性讀出。為了解決這個問題,就需要放大器在讀取cell存儲的數據后,利用暫存的cell電壓寫回字線單元行。
cell存儲陣列
2)DRAM刷新
由于cell的電容很小,并且CMOS晶體管在關閉的時候,也存在漏電,這樣電容上的電荷也在隨著時間的變化,逐漸變少。時間一長,存儲的信息就會丟失。為了解決這一問題,具體做法是對于每個單元行,每過一段時間就自主地進行讀取,等放大器暫存好信息后就立刻將其寫回行。關于單元行的刷新時機也很有講究,一般每64ms內就要對cell陣列進行一次全面刷新。
3.2 DRAM的讀寫
cell陣列+外圍邏輯
1) DRAM讀過程
在讀取DRAM芯片上單個比特數據時:* 讀取前,先給各條位線預充電(也稱為precharge),即把位線電壓拉高到供電電壓的一半。拉高到一半的目的是和cell電容電壓形成電壓差,從而在打開單元行時,可利用電容的微弱充放電產生電壓波動。預充電完成后,就可以斷開位線與預充電電源的連接,此時位線處于懸空態,電壓會保持為供電電壓的一半。
開始讀取,首先在地址總線上輸入行地址,稍后立刻置“行地址選通”(即RAS)有效,置RAS有效后,DRAM芯片就把行地址緩存下來。
緩存好行地址之后,就把行地址送入譯碼模塊,譯碼模塊把行地址譯碼成獨熱碼,獨熱碼的每一位都接到對應的字線,然后把其中一條字線的電壓值拉高。
把地址線上的地址從行地址轉換成列地址,轉換成列地址之后,外界會置“列地址選通”有效,然后DRAM會把列地址緩存起來。
拉高的字線所對應的單元行被打開,即單元行的所有晶體管導通,單元行的各個cell電容和位線連通。 如果cell保存比特信息1,即cell電容的電壓等于供電電壓,此時cell電容電壓高于位線電壓,電容放電,位線的電壓稍稍上升。 如果cell保存比特信息0,即cell電容的電壓等于地電壓,即0電壓,此時位線電壓高于cell電容電壓,位線向cell電容充電,位線電壓稍稍下降。
放大器捕捉位線上的微弱電壓波動,通過“差分感測”在本地生成并暫存cell電容電壓。 如果cell電容等于供電電壓,那么位線電壓稍稍上升,放大器比較此位線和另一條基準線的電壓,通過模擬電路的反饋來放大兩者的電壓差,最終在本地生成一個等于供電電壓的輸出電壓,并用鎖存器把輸出電壓鎖存下來。 如果cell電容電壓等于0,放大器最終生成等于0的輸出電壓,并用鎖存器把0電壓鎖存下來。
放大器鎖存好行數據之后,把行數據送往多到一選擇器。
列地址緩存就把列地址送到多到一選擇器,多到一選擇器根據列地址,把單元行中的某一位送到輸出線。
輸出之后,還需要把放大器的數據寫回到單元行,即根據放大器的鎖存值,把位線拉高到供電電壓或是0電壓,位線向cell電容充放電,充放電結束之后,就可以關閉字線。
寫回數據并關閉字線之后,連接位線和預充電電源,給位線預充電到供電電壓的一半,為下一次讀寫做好準備。
2) DRAM寫過程
寫過程和讀過程比較類似,就不詳細描述,主要描述有差異的地方:* 位線預充電到供電電壓的一半。
輸入、緩存行地址,譯碼行地址,開通單元行,開通單元行后位線產生電壓波動,放大器捕捉電壓波動并還原、暫存行數據到本地。
輸入、緩存列地址,與此同時置寫使能有效,并在Data Buffer存進寫入比特,注意,Data Buffer在讀取DRAM時用來暫存輸出比特,而在寫DRAM時則用來暫存寫入比特。
把寫入比特送到一到多分配器,分配器根據列地址把寫入比特送到對應的放大器中,放大器根據寫入比特改寫本地暫存值。
放大器根據暫存的電壓值刷新單元行,刷新完畢后斷開單元行的字線。
刷新完畢后,重新給位線預充電,為下一次讀寫做好準備。
總的來說,讀取一個比特的總體過程:獲得行號,譯碼行號,開啟單元行,放大位線電壓波動并暫存數據到放大器,獲得列號并根據列號選擇一位進行輸出,寫回數據,關閉字線,重新預充電。 寫一個比特的總體過程是:獲得行號,譯碼行號,開啟單元行,放大位線電壓波動并暫存數據到放大器,獲得列號并輸入寫入數據,根據列號把寫入數據送到放大器并改寫暫存值,寫回數據,關閉字線,重新預充電。
你可能會疑問,要訪問的一個字節的其他7bit是不是也存在這些單元行里,答案是否定的。 其實,還存在7個這樣的bit存儲陣列,其中相同的行列地址在這7個bit存儲陣列相同位置取出相應的bit,這樣便得到了完整的8bit(一個字節)數據。
另外,在讀寫過程中,時間主要消耗在“開啟單元行”與“放大電壓波動并暫存數據”。 單元行的柵極可以抽象成一個個電容的并聯,因此字線的拉高就是給這么多電容充電的一個過程,這將是很耗時及耗電的。 由于放大器大部分是模擬電路,所以他的工作也不快。 那么怎么提高DRAM的讀寫速度呢? 關鍵點在放大器的緩存區(row buffer),它緩存了單元行,但是一般我們只取出了其中的一個bit。 如果要想提升速寫速度,那就還訪問這個單元行的其他bit,這時會直接從row buffer中取出相應的數據,不需要經歷開啟單元行、放大、讀寫數、寫回的耗時過程。
3.3 DRAM系統層次
DRAM的系統層次如下:channel->DIMM->rank->chip->bank->row/column組成的memory array->存儲cell。
1)銀行
如下是一個8陣列bank。其中每個rank中的行列定位到的小方塊,是一個cell,對應一個bit。行、列組成了一個memory array,即一個bank。8個bank組成了8 bank的陣列,通過行、列地址可以得到8 bit的輸出。
8陣列bank
一個8陣列bank一次讀寫8個比特,一顆存儲芯片上一般含有多個bank。下圖是一顆含有8個bank的存儲芯片的示意圖。芯片每次讀寫都只針對一個bank,因此讀寫地址必須包含一個bank號,bank號用于開啟目標bank,目標bank之外的bank是不工作的。
包含8個8陣列bank的存儲芯片
2)Rank和DIMM
電腦用的內存芯片都嵌在一個電路板上,把這個電路板插入內存插槽后,就可增加電腦內存。電路板和板上的芯片,就是所謂的內存條,也稱為DIMM條。內存條通過“內存通道”連接到內存控制器,一組可以被一個內存通道同時訪問的芯片稱作一個rank。一個rank中的每個芯片,都共用內存通道提供的地址線、控制線和數據線,同時每個芯片都提供一組輸出線,這些輸出線組合起來就是內存條的輸出線。
對于一個包含8顆芯片的DIMM條。這8顆芯片被一個內存通道同時訪問,所以它們合稱為一個rank。有的DIMM條有兩面,即兩面都有內存芯片,這種DIMM條擁有兩個rank。
若每個芯片都包含8個bank,每個bank都包含8個陣列,那么這條內存條就可以一次讀寫8×8=64比特,其中第一個8是指每個芯片輸出8位,第二個8是指這個rank總共有8顆芯片,因為這8顆芯片被同一個內存通道訪問,所以其被訪問的bank和bank內的行地址、列地址都是完全一致的。下圖是一個描述這個過程的簡圖:顯然,我們在讀寫8顆芯片同一個bank同一個位置的cell。注意,圖中沒有顯示不在工作狀態的bank。對一個rank讀寫,即同時讀寫rank內8個存儲芯片內的同一位置的bank。
rank讀寫
電腦有時候可以插入多個內存條,多個內存條有助于提升電腦的內存容量,但是未必能提高電腦的速度。電腦的速度受“內存通道”數限制,如果電腦有四個插槽,卻只有一個內存通道,那么CPU仍然只能一次訪問一個rank。但如果電腦有四個插槽的同時還有四個內存通道,那么CPU就可以一次訪問四個rank,很顯然,四并行訪問明顯比串行訪問快,假設每個rank可以輸出64比特,那么四通道就可以一次訪問4×64=256比特,而單通道只能訪問64比特。
3.4 DRAM訪問加速
1)burst模式
由于現在的處理器,CPU與DDR之間基本上都有cache,CPU在訪問內存單個字的時候,不僅需要訪問這個字,還需要把這個字所在的緩存行全部搬進cache中,因此內存不僅要一次提供一個字,還要提供一個緩存行(cache line)。緩存行一般比較大,比如8個64比特,因此內存要一次提供8×64=512比特數據。但如果前面介紹的方式訪問內存,那么一次只能提取出64比特,即提取一個字,這并不滿足緩存行的要求。為此,我們提出對內存使用“burst模式”。
由于緩存行內的各個字在內存上是緊鄰的,我們就可以靈活地使用cell陣列中的行緩存(row buffer)。前面說到單元行進入放大器的行緩存之后,并不會在讀寫一個比特后立刻寫回cell陣列,而是待在行緩存里等待下一個讀寫命令。如果下一個讀寫命令仍然發生在該單元行,那就可以行命中,直接操作row buffer。
在burst模式里,每當我們讀取cell陣列中的一個比特,不僅把這個比特送到輸出緩存中,而且緊接著把這個比特所在緩存行的各個比特都送到輸出緩存,這樣就完成了一次burst,即把目標比特周圍的多個比特連續地讀出。
2)bank并行和內存交錯
前面我們比較詳細地聊了在一個cell陣列中讀取數據的過程,而CPU在訪問內存時,還需要一些別的操作??偟膩碚f,CPU訪存大概要經過5個步驟:
1, CPU發送指令給內存控制器。
2, 內存控制器解析指令,并把“解析到的控制信息”發送到控制總線。
3, bank接收控制信息,并讀取數據。
4, 內存芯片把讀取出的數據放到數據總線。
5, 內存控制器收取數據,并將其交給CPU。
如果CPU連續訪問同一bank,那么CPU、內存控制器、總線和bank就必須串行操作,串行操作會讓訪存效率下降。我們假設CPU不可以在一個bank工作時,再給它發送新的指令。如果CPU連續不斷地給一個bank發送指令,那么很可能前一個指令還沒完成,后一個指令就改變了bank內的row buffer、列地址緩存或輸出緩沖。
為了說明cpu訪存過程中帶來的時間消耗和造成的效率下降,下面以“總線延遲”為例:
光速是3×10^8m/s,而高性能CPU的頻率可達3GHz,即3×10^9Hz。那么在CPU的一個時鐘周期內,光可以運動10cm。但是電在硅中的傳播距離大約是光的五分之一,經過測量,在電子線路中 電在一個CPU時鐘周期內只能運動20mm左右。而CPU和內存芯片之間的距離遠不止20mm,因此數據在總線上移動需要花費多個CPU時鐘周期。
上面的計算說明,在CPU訪存的5個步驟中,第2、第4步是要花很多時間的,而沒有詳細討論的第1、第5步,大概率比這兩步還要慢。因此讓CPU、內存控制器、總線和bank串行操作是不明智的。實際上,我們完全可以在一個bank進行第3步時,讓CPU、內存控制器、總線去操作新的bank,以此隱藏起它們的工作時間,從而營造起一種CPU、內存控制器和總線不需要消耗時間的假象。上面這種做法實現了“bank間并行”。
所謂在“bank間并行”就是讓一個chip內的不同bank并行工作,讓它們各干各的。為此CPU要連續、依次向不同的bank發送讀取指令,這樣在同一時間很多bank都在工作,第一個bank可能在輸出,第二個bank可能在放大電壓,第三個bank可能在開啟單元行。當第一個bank burst輸出完畢,第二個bank剛好可以輸出。當第二個bank burst輸出完畢,第三個bank剛好可以輸出.......通過這樣讓“bank讀取”和“CPU、內存控制器、總線工作”在時間上相互重疊的方式,我們可以成功地把CPU、內存控制器和總線的工作時間隱藏起來,從而打造出一種CPU無延遲訪問內存、多個bank連續、依次“泵”出數據的理想情況。這種通過“bank間并行”實現“連續泵出數據”的方法,就是所謂的“內存交錯”。
內存交錯不僅隱藏了CPU、內存控制器和總線的工作時間,還隱藏了對單個bank而言row缺失所造成的多余訪問時間(所謂“多余”是相對“row 命中”情況而言的),連續兩次對同一個bank的訪問,它們訪問的row相同或者不同,對延遲的影響是相當顯著的。
如果第二個命令是對同一個row訪問,那么memory controller只需要發出Rd/Wr讀寫命令即可,稱為行命中。如果第二個命令是對不同的row進行訪問,那么memory controller需要發出PRE,ACT,Rd/Wr命令序列,稱為行缺失。從命令序列的對比來看,可以看出行缺失的情形對性能的影響是糟糕的。下圖顯示了連續的行缺失的情形下的訪存序列:
行缺失的訪問序列
然而,如果我們有多個bank,然后將 A0,A1,A2...的訪存序列,通過memory controller的address interleaving, 映射到多個bank上,也就是所謂banking。避免了連續訪問同一個bank的不同row,造成的大量行缺失,就能夠得到下面的訪存序列:
流水線化的訪問序列
顯然,上圖中的類似流水化的訪問能夠很大程度上掩蓋訪問DRAM的訪存延遲,這也就是banking能夠提高memory throughput的原因。
另外,memory controller的address interleaving是什么呢?
我們都知道在OS層面,有著從virtual address到physical address的地址映射。類似地,在memory controller層面,我們需要將physical address映射為對DRAM chip中具體的位置的訪問,通過將bank映射到物理地址的相對低位(相對于row),可以使得對連續地址的訪存請求被映射到不同的bank。
物理地址的bank映射
審核編輯:湯梓紅
評論
查看更多