3.2《深入理解計算機系統》筆記(二)內存和高速緩存的原理【插圖】
《深入計算機系統》筆記(一)主要是講解程序的構成、執行和控制。接下來就是運行了。我跳過了“處理器體系結構”和“優化程序性能”,這兩章的筆記繼續往後延遲!
《深入計算機系統》的一個很大的用處是:給了我們很多定義式的解釋,或者稱之為科學的解釋,這將成為我的理論依據;不再是網上一些自稱老手的閑聊了。不愧是計算機最牛逼的大學卡內基-梅隆大學的教材。
該blog跳過第四章CPU的結構,第五章優化程序性能,也沒有詳細討論高速緩存的機制。
六、存儲器層次結構
有必要將存儲器層次結構再次列出來:
高速緩存的“行”、“塊”和“組”是什麽意思?參考本bolg最下面“高速緩存的物理邏輯圖”
字:一個word的意思,IA32中指的是16位,
塊:是一個固定大小的信息包,在高速緩存和主存之間來回傳送。塊包含32~64個字節。所以內存中只是信息,成為塊
行:高速緩存中存儲塊已經其他信息的容器。所以,行總是一個塊的大小,通常“行”和“塊”可以互換使用。結合上圖高速緩存既有塊和其他信息,稱之為“行”
組:是一個或者多個行
---》之前知識停留在RAM和ROM,現在再往前推進一步RAM也分為靜態SRAM和動態的DRAM。SRAM主要用於高速緩存DRAM用於內存
SRAM將每個位存儲在一個雙穩態的存儲器單元裏。每個單元是用一個六個晶體管電路來實現。它可以無限期地保持在兩個不同的電壓配置或狀態之一。就是說只要有電,他就會永遠地保持它的值。即使有幹擾,例如電子噪音、擾亂電壓,當幹擾消除時,電路就會恢復到穩定值。下圖說明了“雙穩態的”效果,采用倒擺的時鐘。
難道這個原理可以解釋:電磁幹擾造成電視畫面錯亂,手機信號幹擾麽?
DRAM將沒位存儲為一個電容,這個電容非常小,通常只有30毫微微法拉。與SRAM不同的是DRAM的存儲單元對幹擾非常敏感。當電容電壓沒擾亂之後,他就永遠無法恢復了。所以DRAM需要不斷刷新電容。暴露在光線下會導致電容電壓改變。實際上,數碼照相機和攝像機中的傳感器本質上就是DRAM單元的陣列。【驚訝】
無論如何SRAM和DRAM都是易失的(volatile)
下面討論DRAM的讀取機制:
這種二維陣列的缺點是:必須分兩步發送地址,增加存儲時間。
---》DDR2和DDR3的內存的區別。Double data-rate synchronous DRAM帶寬分別是4位和8位。DDR3也分為1333MHz和1600MHz
---》磁盤,略過。
---》DRAM和磁盤的性能滯後於CPU的新能,雖然他們的性能都在增長。
這也就是為什麽CPU和內存之間的高速緩存一直增多。
---》人們發現無法像以前那樣增大CPU的時鐘頻率了,計算機制造商撞上了“能量墻”因為如果那樣芯片的功耗會太大。所以多核就出現了,多核出現後CPU的時鐘有所減少,並區域平緩。但是有效CPU周期時間還是像之前的速率增長。
---》高速緩存運行機制。p(406)
---》緩沖區命中。
為什麽第二次啟動程序要比第一次快的多,就是因為緩沖區命中的原理。第一次啟動後很多數據還停留在多級緩沖區中,這個時候如果再次啟動就會減少數據移動次數,也就減少程序的啟動時間。從上圖中我們發現,有部分數據存在與高速緩存中,就不用從內存中取了。
舉例子:灌溉小麥,使用100米的水渠(普通水渠,不是水泥那種),假如水泵出水是固定的。
第一次使用時,水渠中的水前進很慢,走完100米的水渠大約需要10分鐘,這是因為:有一些水會損失掉,即被滲到水渠下面的泥土中了。這部分水可以看作是“高級緩存”中的水。
第二次(時間較短)再灌溉小麥時,水渠的水走的很快,花費了2分鐘,因為相對於第一次來說,水渠不需要王下面滲很多水了。如果時間長了,隔了2天,水渠中的滲的水再往下滲。
第三次灌溉(時間較長),同樣需要一些水滲到水渠下泥土裏面,所以,還是需要10分鐘。
用計算機中的實例:當一條加載指令指示CPU從內存地址A讀出一個字時,他將地址A發送給高速緩存。如果高速緩存證保存著A處的地址的按個拷貝,它就立即將那個字發給CPU。這要比從內存中讀取快很多。
---》core i7的高速緩存層次結構
註意:只保存指令的高速緩存i-cache,只保存數據的高速緩存叫d-cache。既保存指令又保存數據的成為統一的高速緩存。
就像第一章說的那樣高速緩存至關重要,特別是“緩沖區命中”這個技術如果優化好了,速度將會很大改進。
高速緩存的物理邏輯圖:
---》直接映射高速緩存p(410)
根據E(高速緩存行)高速緩存被分為不同的類。每個組只有一行(E=1)的高速緩存唄稱為直接映射高速緩存 雖然一個整形可能在寄存器中,而整形數組,則可能存在與高速緩存中。
---》沖突不命中。請看下面的例子:
[cpp] view plain copy
- float dotprod(float x[8], float y[8])
- {
- float sum = 0.0;
- int i;
- for(i = 0;i < 8;i++)
- sum += x[i] * y[i];
- return sum;
- }
當第一次叠代x[0]時,必定不命中,那麽會導致x[0]~x[3]的塊被加載到高速緩沖組0,下一次是y[0]的調用,又一次不命中,導致y[0]~y[3]的塊被拷貝到組0,從而覆蓋前一次x的值。如此叠代,下次x[1]的值繼續不命中,繼而將x[0]~x[3],覆蓋調y[0]~y[3]的值。這種就叫做沖突不命中,也叫”抖動“。本質原因是:x和y數組被映射到同一個組。程序員可以避開這種抖動,但是我覺得編譯器應該解決這個問題。
原書中可能錯誤的地方不算多,但也影響到閱讀的心情。
p406圖6-24少了一個10的單元格,12單元格重復
p403圖6-21 a)函數名字應該為:int sumarraycol(int a[m][n]).
p199第一行最後應該為“偏移量”
3.2《深入理解計算機系統》筆記(二)內存和高速緩存的原理【插圖】