不管是臺式機還是筆記本的CPU,處理器的二/三緩存都是極其重要的一個數量,一方面是被廠家宣傳的重點,另一方面也確實影響著電腦的速度。同時在內存不足的電腦裡,增加內存對系統的性能提升往往有著立杆見影的效果。於是玩家不禁要問,為什麼CPU的緩存和內存對系統的性能影響這麼大呢?這就得從計算機的存儲系統的工作方式和原理談起。
存儲器是計算機中用於存放指令和數據的部件。計算機在處理數據時,中央處理器從存儲器讀出指令,再按照指令中的地址從存儲器中讀出數據,按照指令要求對數據進行操作。中央處理器的高速運算要求存儲器要在很短的時間內完成指令和數據的存取操作。
隨著對計算機性能的要求越來越高,現代計算機對存儲系統有三個基本要求,即:存取時間短(速度快)、存儲容量大和價格成本低。而容量越大存取的時間就會長,速度越快,價格就越高。為了解決這個問題,便採用了高速緩衝存儲器,主存儲器和輔助存儲器3個部分組成。
計算機各種存儲及其特點
其中寄存器(Registe)是用於CPU內部各單元之間的周轉,是CPU內部用來創建和儲存CPU運算結果和其它運算結果的地方,擁有非常高的讀寫速度,裡面的數據是下一步必然會用到的,所以寄存器不屬於層次結構存儲器。CPU內部的寄存器有很多種類型。CPU對存儲器中的數據進行處理時,往往先把數據取到內部寄存器中,而後再作處理。外部寄存器是計算機中其它一些部件上用於暫存數據的寄存器,它與CPU之間通過「埠」交換數據,外部寄存器具有寄存器和內存儲器雙重特點。而通用寄存器的數據寬度決定了處理器一次可以運行的數據量。
64位技術的寄存器變化
X86-64技術就是新增的幾組CPU寄存器將提供更快的執行效率。標準的32位的x86架構包括8個通用寄存器,AMD在64 位X86架構中又增加了8組,將寄存器的數目提高到了16組。X86-64寄存器默認位64-bit。還增加了8組128-bit XMM寄存器,將能給單指令多數據流技術運算提供更多的空間,這些128位的寄存器將提供在矢量和標量計算模式下進行128位雙精度處理,為3D建模、矢量分析和虛擬實境的實現提供了硬體基礎。通過提供了更多的寄存器,按照X86-64標準生產的CPU可以更有效的處理數據,可以在一個時鐘周期中傳輸更多的信息。
高速緩衝存儲器就是我們平常所說的CPU緩存,通常包括一級、二級緩存,過去的高端產品還會有三級緩存,現在中低端產品也有L3了,比如AMD羿龍II雙核系列,Intel的i3系列。關於高速緩存,後面會有更詳細的介紹。
主存儲器就是我們常說的內存條。高速緩衝存儲器和主存儲器(內存條)由於可以直接被CPU讀取,故稱之為內存儲器。
輔助存儲器主要是指硬碟,而海量存儲器則是指過去主要用的磁帶機一類的設備,現在隨便硬碟技術的提升,輔助存儲器也可以達到「海量」的標準。而且現在的輔助存儲器一般都帶有自身的緩存。
介紹完存儲結構後,可能會產生一個疑問,那就是為什麼層次結構存儲器會加速計算機的速度,或者說層次結構的依據是什麼?
【每日焦點】單碟王再現 日立500GB廉價硬碟首測
下面就得引入必備的「程序的局部性原理」知識了。
程序的局部性原理:是指程序在執行時呈現出局部性規律,即在一段時間內,整個程序的執行僅限於程序中的某一部分。相應地,執行所訪問的存儲空間也局限於某個存儲區域。局部性原理又表現為:時間局部性(temporal locality)和空間局部性(spatial locality)。
程序的調用返回行為
時間局部性是指如果程序中的某條指令一旦執行,則不久之後該指令可能再次被執 行;如果某數據被訪問,則不久之後該數據可能再次被訪問。
空間局部性
空間局部性是指一旦程序訪問了某個存儲單元,則不久之後。其附近的存儲單元也將被訪問。
空間局部性和時間局部性是有區別的。空間局部性指執行涉及很多簇聚的存儲器單元的趨勢,這反映了處理器順序訪問指令的傾向,同時,也反映了程序順序訪問數據單元的傾向,如處理數據表。時間局部性指處理器訪問最近使用過的存儲器單元的趨勢,例如,當執行一個循環時,處理器重複執行相同的指令集合。
傳統上,時間局部性是通過將最近使用的指令和數據值保存到高速緩存中並使用高速緩存的層次結構實現的。空間局部性通常是使用較大的高速緩存並將預取機制集成到高速緩存控制邏輯中實現的。
舉例:當硬碟受到CPU指令控制開始讀取數據時,硬碟上的控制芯會控制磁頭把正在讀取的簇的下一個或者幾個簇中的數據讀到硬碟的緩存中(由於硬碟上數據存儲時是比較連續的,所以讀取命中率較高),當需要讀取下一個或者幾個簇中的數據的時候,硬碟則不需要再次讀取數據,直接把緩存中的數據傳輸到內存中就可以了,由於速度遠遠高於磁頭讀寫的速度,所以能夠達到明顯改善能的目的,即根據空間局部性原理,預測下一步所需要的數據,並將其提前寫入內存。
為了保證CPU訪問時有較高的命中率,內存儲器(包括CPU緩存和內存)中的內容應該按一定的算法替換。較常用的算法是「最近最少使用算法」(LRU算法),它是將最近一段時間內最少被訪問過的行淘汰出局。因此需要為每行設置一個計數器,LRU算法是把命中行的計數器清零,其他各行計數器加1。當需要替換時淘汰行計數器計數值最大的數據行出局。這是一種高效、科學的算法,其計數器清零過程可以把一些頻繁調用後再不需要的數據淘汰出,提高利用率。這樣內存儲器中的數據在更新的時候則會根據時間局布性原理把讀取頻率高的及其周圍的相關數據留下,把低導入虛擬內存或者淘汰掉(關於虛擬內存後面會有描述)。
在層次存儲結構中的每一級都採用程序局部分布原理的原理來預讀和更替數據。由於預讀的命中率很高,故續約了時間,這也是採用層次存儲結構的基礎。
現在高速緩存的概念已被擴充,不僅在CPU和主內存之間有高速緩存而且在內存和硬碟之間也有Cache(磁碟高速緩存),乃至在硬碟與網絡之間也有某種意義上的 Cache(Internet 臨時文件夾)——凡是位於速度相差較大的兩種硬體之間的,用於協調兩者數據傳輸速度差異的結構,均可稱之為Cache。Cache與上下流之間的數據交換都是程序局部性原理。這次我們主要討論CPU的高速緩存,前面已經介紹了CPU高速緩存是內存儲器的一種,下面將介紹其產生的原因及演變。
早期計算機的CPU與主存的工作速度較為接近,主內存的速度並不影響整機的運算速度。隨著IC設計和半導體製造工藝的發展,CPU的運行速度遠高於主內存的速度。這要求系統中主存的存取速度提高,存儲容量增大。而主存儲器一般採用DRAM (動態隨機存儲器) ,其容量的提高是比較快的,但是讀取速度的提高卻很慢,因此在速度上與CPU主頻的提高產生了不相配的情況。為解決高速CPU 與低速內存之間的速度差異,最經濟、有效的方法是在兩者之間插入容量不大但操作速度很高的存儲器高速緩存(Cache) ,起到緩衝作用,解決了兩者速度的平衡和匹配問題,對微處理器整體性能有很大提高。
486時代的兩個代表產品486DX和486SX
早期的80486相當於把80386和完成浮點運算的數學協處理器80387以及8kB的高速緩存集成到一起,這種片內高速緩存稱為一級(L1)緩存,80486還支持主板上的二級(L2)緩存。緩存概念由此誕生,並一直延續到今天成為影響CPU性能的重要因素。
四核Nehalem架構擁有高達8M的三級高速緩存
隨著CPU製造工藝的發展,二級緩存和三級緩存也能輕易的集成在CPU內核中,容量也在逐年提升。至今,在中低端產品中集成三級緩存的CPU也不少見。
當然,有人可能要問,為什麼不直接把內存的速度提高到和緩存一樣快呢?這涉及到兩個方面,為了得到更高的速度,那信號的發射頻率必須提升,而為了得到更大的容量,就必須減少集成電路中信號傳輸中存在幹擾,幹擾與傳播速度又正相關,如果頻率提高,幹擾就會增強,所以兩者比較難以統一。
構成緩存的6T SRAM電晶體結構圖
另一方面是「經濟」原因,高速緩存緩存通常都是靜態RAM (SRAM),速度是非常的快, 但是靜態RAM集成度低,存儲相同的數據,靜態RAM的體積是動態RAM的6倍,高同容量的靜態RAM價格是動態RAM的四倍。這就限制了靜態RAM容量的進一步擴大,同時緩存大小也成了CPU級別的一個重要標誌。
雖然我們知道了高速緩存可以大幅的提高CPU的速度,那麼,它們工作的具體原理是什麼呢?
當CPU處理數據時,它會先到Cache中去尋找,如果數據因之前的操作已經讀取而被暫存其中,就不需要再從內存中讀取數據——由於CPU的運行速度一般比主內存的讀取速度快,主存儲器周期(訪問主存儲器所需要的時間)為數個時鐘周期。因此若要訪問主內存的話,就必須等待數個CPU周期從而造成浪費。
Cache 的邏輯結構
Cache由控制和存儲器2部分組成,如上圖所示,其中虛線框內為控制部分。Cache的存儲器中存放著主存的部分拷貝,其控制部分有3 個功能:
(1) 判斷要訪問的數據是否在Cache中,若在,為命中;否則,為未命中。
(2) 命中時,進行Cache 的尋址。
(3) 未命中時,按替換原則,確定主存中的信息塊要讀入到Cache 中的哪個信息塊空間。
CPU在緩存中找到有用的數據被稱為命中,當緩存中沒有CPU所需的數據時(這時稱為未命中),CPU才訪問內存。從理論上講,在一顆擁有一級緩存的CPU中,讀取一級緩存的命中率為80%。也就是說CPU一級緩存中找到的有用數據佔數據總量的80%,剩下的20%從二級緩存中讀取。由於不能準確預測將要執行的數據並將其預讀到緩存中,讀取二級緩存的命中率也在80%左右(從二級緩存讀到有用的數據佔總數據的16%)。那麼還有的數據就不得不從內存調用,但這已經是一個相當小的比例了。較高端的CPU中,還會帶有三級緩存,它是為讀取二級緩存後未命中的數據設計的—種緩存,在擁有三級緩存的CPU中,只有約5%的數據需要從內存中調用,這進一步提高了CPU的效率。
擁有144MB緩存的八路IBM POWER5處理器
但這個比例也不是絕對的,因為隨著軟體的發展,需要越來越多的緩存來預存將要運算的數據,如果緩存的容量不隨著軟體的發展而增大,就會出現不夠用的情況。
另外在處理器緩存的發展中,Intel和AMD的處理器一級緩存在邏輯結構設計上在Core之前並不一樣。AMD對一級緩存的定位是「實數據讀寫緩存」,基於該架構的一級數據緩存主要用於存儲CPU最先讀取的數據;而更多的讀取數據則分別存儲在二/三級緩存和系統內存當中。即二級/三級緩存中的一部分數據都要在一定的規則下搬到一級緩存中。二級緩存的容量自然對AMD CPU的整體性能影響小些。相對的,AMD則總是試圖把一級緩存做的更大些。
Intel在對Core之前一級緩存的理解是「數據代碼指令追蹤緩存」,即是說一級緩存中存儲的其實只是二級緩存中數據的地址,而不是這些數據的複製。由於一級數據緩存不再存儲實際數據,因此「數據代碼指令追蹤緩存」設計能夠極大地降CPU對一級數據緩存容量的要求,降低處理器的生產難度。但這種設計的弊端在於數據讀取效率較「實數據讀寫緩存設計」低,而且對二級緩存容量的依賴性非常大。
事實上CPU性能對二級緩存容量的「敏感」與否還受到諸如內存控制器,流水線長度、頻率、總線架構和指令集等等多方面的影響。在多核CPU中還關乎各個物理內核之間的數據交換問題。從Core開始,Intel開始採用「實數據讀寫緩存」,而目前最新的Nehalm架構則像AMD一樣,把內存控制器集成在CPU內部,並更新了總線。這一方面說明了AMD在CPU架構設計上的強項,另一方面在Intel採用AMD的這種佔優勢的存儲架構之後,AMD的優勢將被進一步削弱。
這裡還涉及到一個問題:CPU提供給Cache的地址是主存的地址,要訪問Cache,就必須將這個地址變換成Cache 的地址,這種地址變換為地址映射,Cache的地址映射有直接映射、全相聯映射和組相聯映射三種,目前的主流CPU都是採用組相聯。
我們常說的虛擬內存與前面的層次存儲結構是不一樣。先看虛擬內存的定義:虛擬內存是計算機系統內存管理的一種技術。它使得應用程式認為它擁有連續的可用的內存(一個連續完整的地址空間),而實際上,它通常是被分隔成多個物理內存碎片,還有部分暫時存儲在外部磁碟存儲器上,在需要時進行數據交換。虛擬內存就是當物理內存不足夠的時候,把硬碟的一部分當作內存內部數據的周轉,而不是當做內存來使用。
虛擬內存原理
比如當我們運行某程序時候佔用了15M,不管此時內存的空閒空間夠不夠15M,系統都會用虛擬內存技術在硬碟上指定了一個虛擬空間,如果我們的物理內存夠用,則此時這個虛擬空間裡面沒有信息而已 。當物理內存不足的時候,系統則會將些時內存裡暫時用不上的程序存放到原先給它指定的虛擬空間中,然後留出地方給新的程序使用,在物理內存再次空閒,或者被存入虛擬空間的程序需要再次運行時,便會再將其讀入內存。這樣一個循環交換過程就是虛擬內存技術,為什麼叫它虛擬呢,因為系統把文件釋放到了硬碟上,而這個硬碟可不是內存,只是臨時的保存內存信息的地方,這個區域並不可以被CPU讀取和運算。
如果沒有虛擬內存技術,我們在物理內存不夠用的時候根本就啟動不了新的程序,因為新的程序不能在內存中寫入相關信息。虛擬內存的功能和作用都不屬於計算機的層次存儲結構,僅僅是作業系統單獨對內存的一種管理方案。
虛擬內存設置頁
現在主流的配機內存已經升級到2G,稍微好點兒的都採用了4G,這樣大的內存很少出現用滿的情況,於是有人提出是不是可以禁用虛擬內存?不可以,至少在目前的軟體環境這樣做是不行的,因為從1961年虛擬內存誕生以來,虛擬內存技術已經成各種計算機作業系統和許多應用軟體在編寫時的一個規範,即使主內存足夠用,有些程序也仍然需要虛擬內存的支持,如果禁掉虛擬內存會影響系統的穩定性和程序的兼容性。
本文總結:
本文講述了計算機的存儲層次,其中以CPU的高速緩存為主,而且其它的方面如硬碟的緩存,內存與硬碟之間都採取了與CPU高速緩存相同的原理來實現系統的加速。
提供「高速緩存」的目的是為了讓數據訪問的速度適應CPU的處理速度,其基於的原理是內存中「程序執行與數據訪問的局部性原理」,即一定程序執行時間和空間內,被訪問的代碼集中於一部分。為了充分發揮高速緩存的作用,不僅依靠「暫存剛剛訪問過的數據」,還要使用硬體實現的指令預測與數據預取技術——儘可能把將要使用的數據預先從內存中取到高速緩存裡。
可以這麼說,以CPU緩存為代表的所有的層次存儲結構都是以程序局部性原理為基礎的空間換取速度。另外,CPU的寄存器和虛擬內存雖然不屬於層次存儲結構,但對計算機的速度和程序運行的穩定性都有非常積極的意義。