<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 第?17?章?計算機體系結構基礎 **目錄** + [1\. 內存與地址](ch17s01.html) + [2\. CPU](ch17s02.html) + [3\. 設備](ch17s03.html) + [4\. MMU](ch17s04.html) + [5\. Memory Hierarchy](ch17s05.html) 現代計算機都是基于Von Neumann體系結構的,不管是嵌入式系統、PC還是服務器。這種體系結構的主要特點是:CPU(CPU,Central Processing Unit,中央處理器,或簡稱處理器Processor)和內存(Memory)是計算機的兩個主要組成部分,內存中保存著數據和指令,CPU從內存中取指令(Fetch)執行,其中有些指令讓CPU做運算,有些指令讓CPU讀寫內存中的數據。本章簡要介紹組成計算機的CPU、內存和設備以及它們之間的關系,為后續章節的學習打下基礎。 ## 1.?內存與地址 **圖?17.1.?郵箱的地址** ![郵箱的地址](https://box.kancloud.cn/2016-04-02_56ff80d380066.png) 我們都見過像這樣掛在墻上的很多個郵箱,每個郵箱有一個房間編號,根據房間編號找到相應的郵箱投入信件或取出信件。內存與此類似,每個內存單元有一個地址(Address),內存地址是從0開始編號的整數,CPU通過地址找到相應的內存單元,取其中的指令或者讀寫其中的數據。與郵箱不同的是,一個地址所對應的內存單元不能存很多東西,只能存一個字節,以前講過的`int`、`float`等多字節的數據類型保存在內存中要占用連續的多個地址,這種情況下數據的地址是它所占內存單元的起始地址。 ## 2.?CPU CPU總是周而復始地做同一件事:從內存取指令,然后解釋執行它,然后再取下一條指令,再解釋執行。CPU最核心的功能單元包括: * 寄存器(Register),是CPU內部的高速存儲器,像內存一樣可以存取數據,但比訪問內存快得多。隨后的幾章我們會詳細介紹x86的寄存器`eax`、`esp`、`eip`等等,有些寄存器只能用于某種特定的用途,比如`eip`用作程序計數器,這稱為特殊寄存器(Special-purpose Register),而另外一些寄存器可以用在各種運算和讀寫內存的指令中,比如`eax`寄存器,這稱為通用寄存器(General-purpose Register)。 * 程序計數器(PC,Program Counter),是一種特殊寄存器,保存著CPU取下一條指令的地址,CPU按程序計數器保存的地址去內存中取指令然后解釋執行,這時程序計數器保存的地址會自動加上該指令的長度,指向內存中的下一條指令。 * 指令譯碼器(Instruction Decoder)。CPU取上來的指令由若干個字節組成,這些字節中有些位表示內存地址,有些位表示寄存器編號,有些位表示這種指令做什么操作,是加減乘除還是讀寫內存,指令譯碼器負責解釋這條指令的含義,然后調動相應的執行單元去執行它。 * 算術邏輯單元(ALU,Arithmetic and Logic Unit)。如果譯碼器將一條指令解釋為運算指令,就調動算術邏輯單元去做運算,比如加減乘除、位運算、邏輯運算。指令中會指示運算結果保存到哪里,可能保存到寄存器中,也可能保存到內存中。 * 地址和數據總線(Bus)。CPU和內存之間用地址總線、數據總線和控制線連接起來,每條線上有1和0兩種狀態。如果在執行指令過程中需要訪問內存,比如從內存讀一個數到寄存器,執行過程可以想像成這樣: **圖?17.2.?訪問內存讀數據的過程** ![訪問內存讀數據的過程](https://box.kancloud.cn/2016-04-02_56ff80d3951f7.png) 1. CPU內部將寄存器對接到數據總線上,使寄存器的每一位對接到一條數據線,等待接收數據。 2. CPU通過控制線發一個讀請求,并且將內存地址通過地址線發給內存。 3. 內存收到地址和讀請求之后,將相應的內存單元對接到數據總線的另一端,這樣,內存單元每一位的1或0狀態通過一條數據線到達CPU寄存器中相應的位,就完成了數據傳送。 往內存里寫數據的過程與此類似,只是數據線上的傳輸方向相反。 上圖中畫了32條地址線和32條數據線,CPU寄存器也是32位,可以說這種體系結構是32位的,比如x86就是這樣的體系結構,目前主流的處理器是32位或64位的。地址線、數據線和CPU寄存器的位數通常是一致的,從上圖可以看出數據線和CPU寄存器的位數應該一致,另外有些寄存器(比如程序計數器)需要保存一個內存地址,因而地址線和CPU寄存器的位數也應該一致。處理器的位數也稱為字長,字(Word)這個概念用得比較混亂,在有些上下文中指16位,在有些上下文中指32位(這種情況下16位被稱為半字Half Word),在有些上下文中指處理器的字長,如果處理器是32位那么一個字就是32位,如果處理器是64位那么一個字就是64位。32位計算機有32條地址線,地址空間(Address Space)從0x00000000到0xffffffff,共4GB,而64位計算機有更大的地址空間。 最后還要說明一點,本節所說的地址線、數據線是指CPU的內總線,是直接和CPU的執行單元相連的,內總線經過MMU和總線接口的轉換之后引出到芯片引腳才是外總線,外地址線和外數據線的位數都有可能和內總線不同,例如32位處理器的外地址總線可尋址的空間可以大于4GB,到[第?4?節 “MMU”](ch17s04.html#arch.mmu)再詳細解釋。 我們結合[表?1.1 “一個語句的三種表示”](intro.program.html#intro.instruction)看一下CPU取指執行的過程。 **圖?17.3.?CPU的取指執行過程** ![CPU的取指執行過程](https://box.kancloud.cn/2016-04-02_56ff80d3a6197.png) 1. ``eip`寄存器指向地址0x80483a2,CPU從這里開始取一條5個字節的指令,然后`eip`寄存器指向下一條指令的起始地址0x80483a7。` 2. CPU對這5個字節譯碼,得知這條指令要求從地址0x804a01c開始取4個字節保存到`eax`寄存器。 3. 執行指令,讀內存,取上來的數是3,保存到`eax`寄存器。注意,地址0x804a01c~0x804a01f里存儲的四個字節不能按地址從低到高的順序看成0x03000000,而要按地址從高到低的順序看成0x00000003。也就是說,對于多字節的整數類型,低地址保存的是整數的低位,這稱為小端(Little Endian)字節序(Byte Order)。x86平臺是小端字節序的,而另外一些平臺規定低地址保存整數的高位,稱為大端(Big Endian)字節序。 4. CPU從`eip`寄存器指向的地址取一條3個字節的指令,然后`eip`寄存器指向下一條指令的起始地址0x80483aa。 5. CPU對這3個字節譯碼,得知這條指令要求把`eax`寄存器的值加1,結果仍保存到`eax`寄存器。 6. 執行指令,現在`eax`寄存器中的數是4。 7. CPU從`eip`寄存器指向的地址取一條5個字節的指令,然后`eip`寄存器指向下一條指令的起始地址0x80483af。 8. CPU對這5個字節譯碼,得知這條指令要求把`eax`寄存器的值保存到從地址0x804a018開始的4個字節。 9. 執行指令,把4這個值保存到從地址0x804a018開始的4個字節(按小端字節序保存)。 ## 3.?設備 CPU執行指令除了訪問內存之外還要訪問很多設備(Device),如鍵盤、鼠標、硬盤、顯示器等,那么它們和CPU之間如何連接呢?如下圖所示。 **圖?17.4.?設備** ![設備](https://box.kancloud.cn/2016-04-02_56ff80d3bc9ac.png) 有些設備像內存芯片一樣連接到處理器的地址總線和數據總線,正因為地址線和數據線上可以掛多個設備和內存芯片所以才叫“總線”,但不同的設備和內存芯片應該占不同的地址范圍。訪問這種設備就像訪問內存一樣,按地址讀寫即可,但和訪問內存不同的是,往一個地址寫數據只是給設備發一個命令,數據不一定要保存,而從一個地址讀數據也不一定是讀先前保存在這個地址的數據,而是得到設備的當前狀態。設備中可供讀寫訪問的單元通常稱為設備寄存器(注意和CPU寄存器不是一回事),操作設備的過程就是讀寫這些設備寄存器的過程,比如向串口發送寄存器里寫數據,串口設備就會把數據發送出去,讀串口接收寄存器的值,就可以讀取串口設備接收到的數據。 還有一些設備集成在處理器芯片中。在上圖中,從CPU核引出的地址和數據總線有一端經總線接口引出到芯片引腳上了,還有一端沒有引出,而是接到芯片內部集成的設備上,無論是在CPU外部接總線的設備還是在CPU內部接總線的設備都有各自的地址范圍,都可以像訪問內存一樣訪問,很多體系結構(比如ARM)采用這種方式操作設備,稱為內存映射I/O(Memory-mapped I/O)。但是x86比較特殊,x86對于設備有獨立的端口地址空間,CPU核需要引出額外的地址線來連接片內設備(和訪問內存所用的地址線不同),訪問設備寄存器時用特殊的`in`/`out`指令,而不是和訪問內存用同樣的指令,這種方式稱為端口I/O(Port I/O)。 從CPU的角度來看,訪問設備只有內存映射I/O和端口I/O兩種,要么像內存一樣訪問,要么用一種專用的指令訪問。其實訪問設備是相當復雜的,計算機的設備五花八門,各種設備的性能要求都不一樣,有的要求帶寬大,有的要求響應快,有的要求熱插拔,于是出現了各種適應不同要求的設備總線,比如PCI、AGP、USB、1394、SATA等等,這些設備總線并不直接和CPU相連,CPU通過內存映射I/O或端口I/O訪問相應的總線控制器,通過總線控制器再去訪問掛在總線上的設備。所以上圖中標有“設備”的框可能是實際的設備,也可能是設備總線的控制器。 在x86平臺上,硬盤是掛在IDE、SATA或SCSI總線上的設備,保存在硬盤上的程序是不能被CPU直接取指令執行的,操作系統在執行程序時會把它從硬盤拷貝到內存,這樣CPU才能取指令執行,這個過程稱為加載(Load)。程序加載到內存之后,成為操作系統調度執行的一個任務,就稱為進程(Process)。進程和程序不是一一對應的。一個程序可以多次加載到內存,成為同時運行的多個進程,例如可以同時開多個終端窗口,每個窗口都運行一個Shell進程,而它們對應的程序都是磁盤上的`/bin/bash`文件。 操作系統(Operating System)本身也是一段保存在磁盤上的程序,計算機在啟動時執行一段固定的啟動代碼(稱為Bootloader)首先把操作系統從磁盤加載到內存,然后執行操作系統中的代碼把用戶需要的其它程序加載到內存。操作系統和其它用戶程序的不同之處在于:操作系統是常駐內存的,而其它用戶程序則不一定,用戶需要運行哪個程序,操作系統就把它加載到內存,用戶不需要哪個程序,操作系統就把它終止掉,釋放它所占的內存。操作系統最核心的功能是管理進程調度、管理內存的分配使用和管理各種設備,做這些工作的程序稱為內核(Kernel),在我的系統上內核程序是`/boot/vmlinuz-2.6.28-13-generic`文件,它在計算機啟動時加載到內存并常駐內存。廣義上操作系統的概念還包括一些必不可少的用戶程序,比如Shell是每個Linux系統必不可少的,而Office辦公套件則是可有可無的,所以前者也屬于廣義上操作系統的范疇,而后者屬于應用軟件。 訪問設備還有一點和訪問內存不同。內存只是保存數據而不會產生新的數據,如果CPU不去讀它,它也不需要主動提供數據給CPU,所以內存總是被動地等待被讀或者被寫。而設備往往會自己產生數據,并且需要主動通知CPU來讀這些數據,例如敲鍵盤產生一個輸入字符,用戶希望計算機馬上響應自己的輸入,這就要求鍵盤設備主動通知CPU來讀這個字符并做相應處理,給用戶響應。這是由中斷(Interrupt)機制實現的,每個設備都有一條中斷線,通過中斷控制器連接到CPU,當設備需要主動通知CPU時就引發一個中斷信號,CPU正在執行的指令將被打斷,程序計數器會指向某個固定的地址(這個地址由體系結構定義),于是CPU從這個地址開始取指令(或者說跳轉到這個地址),執行中斷服務程序(ISR,Interrupt Service Routine),完成中斷處理之后再返回先前被打斷的地方執行后續指令。比如某種體系結構規定發生中斷時跳轉到地址0x00000010執行,那么就要事先把一段ISR程序加載到這個地址,ISR程序是內核代碼的一部分,在這段代碼中首先判斷是哪個設備引發了中斷,然后調用該設備的中斷處理函數做進一步處理。 由于各種設備的操作方法各不相同,每種設備都需要專門的設備驅動程序(Device Driver),一個操作系統為了支持廣泛的設備就需要有大量的設備驅動程序,事實上Linux內核源代碼中絕大部分是設備驅動程序。設備驅動程序通常是內核里的一組函數,通過讀寫設備寄存器實現對設備的初始化、讀、寫等操作,有些設備還要提供一個中斷處理函數供ISR調用。 ## 4.?MMU 現代操作系統普遍采用虛擬內存管理(Virtual Memory Management)機制,這需要處理器中的MMU(Memory Management Unit,內存管理單元)提供支持,本節簡要介紹MMU的作用。 首先引入兩個概念,虛擬地址和物理地址。如果處理器沒有MMU,或者有MMU但沒有啟用,CPU執行單元發出的內存地址將直接傳到芯片引腳上,被內存芯片(以下稱為物理內存,以便與虛擬內存區分)接收,這稱為物理地址(Physical Address,以下簡稱PA),如下圖所示。 **圖?17.5.?物理地址** ![物理地址](https://box.kancloud.cn/2016-04-02_56ff80d3d19ce.png) 如果處理器啟用了MMU,CPU執行單元發出的內存地址將被MMU截獲,從CPU到MMU的地址稱為虛擬地址(Virtual Address,以下簡稱VA),而MMU將這個地址翻譯成另一個地址發到CPU芯片的外部地址引腳上,也就是將VA映射成PA,如下圖所示。 **圖?17.6.?虛擬地址** ![虛擬地址](https://box.kancloud.cn/2016-04-02_56ff80d3e2605.png) 如果是32位處理器,則內地址總線是32位的,與CPU執行單元相連(圖中只是示意性地畫了4條地址線),而經過MMU轉換之后的外地址總線則不一定是32位的。也就是說,虛擬地址空間和物理地址空間是獨立的,32位處理器的虛擬地址空間是4GB,而物理地址空間既可以大于也可以小于4GB。 MMU將VA映射到PA是以頁(Page)為單位的,32位處理器的頁尺寸通常是4KB。例如,MMU可以通過一個映射項將VA的一頁0xb7001000~0xb7001fff映射到PA的一頁0x2000~0x2fff,如果CPU執行單元要訪問虛擬地址0xb7001008,則實際訪問到的物理地址是0x2008。物理內存中的頁稱為物理頁面或者頁幀(Page Frame)。虛擬內存的哪個頁面映射到物理內存的哪個頁幀是通過頁表(Page Table)來描述的,頁表保存在物理內存中,MMU會查找頁表來確定一個VA應該映射到什么PA。 操作系統和MMU是這樣配合的: 1. 操作系統在初始化或分配、釋放內存時會執行一些指令在物理內存中填寫頁表,然后用指令設置MMU,告訴MMU頁表在物理內存中的什么位置。 2. 設置好之后,CPU每次執行訪問內存的指令都會自動引發MMU做查表和地址轉換操作,地址轉換操作由硬件自動完成,不需要用指令控制MMU去做。 我們在程序中使用的變量和函數都有各自的地址,程序被編譯后,這些地址就成了指令中的地址,指令中的地址被CPU解釋執行,就成了CPU執行單元發出的內存地址,所以在啟用MMU的情況下,程序中使用的地址都是虛擬地址,都會引發MMU做查表和地址轉換操作。那為什么要設計這么復雜的內存管理機制呢?多了一層VA到PA的轉換到底換來了什么好處?All problems in computer science can be solved by another level of indirection.還記得這句話嗎?多了一層間接必然是為了解決什么問題的,等講完了必要的預備知識之后,將在[第?5?節 “虛擬內存管理”](ch20s05.html#link.vm)討論虛擬內存管理機制的作用。 MMU除了做地址轉換之外,還提供內存保護機制。各種體系結構都有用戶模式(User Mode)和特權模式(Privileged Mode)之分,操作系統可以在頁表中設置每個內存頁面的訪問權限,有些頁面不允許訪問,有些頁面只有在CPU處于特權模式時才允許訪問,有些頁面在用戶模式和特權模式都可以訪問,訪問權限又分為可讀、可寫和可執行三種。這樣設定好之后,當CPU要訪問一個VA時,MMU會檢查CPU當前處于用戶模式還是特權模式,訪問內存的目的是讀數據、寫數據還是取指令,如果和操作系統設定的頁面權限相符,就允許訪問,把它轉換成PA,否則不允許訪問,產生一個異常(Exception)。異常的處理過程和中斷類似,不同的是中斷由外部設備產生而異常由CPU內部產生,中斷產生的原因和CPU當前執行的指令無關,而異常的產生就是由于CPU當前執行的指令出了問題,例如訪問內存的指令被MMU檢查出權限錯誤,除法指令的除數為0等都會產生異常。 **圖?17.7.?處理器模式** ![處理器模式](https://box.kancloud.cn/2016-04-02_56ff80d3f4178.png) 通常操作系統把虛擬地址空間劃分為用戶空間和內核空間,例如x86平臺的Linux系統虛擬地址空間是0x00000000~0xffffffff,前3GB(0x00000000~0xbfffffff)是用戶空間,后1GB(0xc0000000~0xffffffff)是內核空間。用戶程序加載到用戶空間,在用戶模式下執行,不能訪問內核中的數據,也不能跳轉到內核代碼中執行。這樣可以保護內核,如果一個進程訪問了非法地址,頂多這一個進程崩潰,而不會影響到內核和整個系統的穩定性。CPU在產生中斷或異常時不僅會跳轉到中斷或異常服務程序,還會自動切換模式,從用戶模式切換到特權模式,因此從中斷或異常服務程序可以跳轉到內核代碼中執行。事實上,整個內核就是由各種中斷和異常處理程序組成的。總結一下:在正常情況下處理器在用戶模式執行用戶程序,在中斷或異常情況下處理器切換到特權模式執行內核程序,處理完中斷或異常之后再返回用戶模式繼續執行用戶程序。 段錯誤我們已經遇到過很多次了,它是這樣產生的: 1. 用戶程序要訪問的一個VA,經MMU檢查無權訪問。 2. MMU產生一個異常,CPU從用戶模式切換到特權模式,跳轉到內核代碼中執行異常服務程序。 3. 內核把這個異常解釋為段錯誤,把引發異常的進程終止掉。 ## 5.?Memory Hierarchy 硬盤、內存、CPU寄存器,還有本節要講的Cache,這些都是存儲器,計算機為什么要有這么多種存儲器呢?這些存儲器各自有什么特點?這是本節要討論的問題。 由于硬件技術的限制,我們可以制造出容量很小但很快的存儲器,也可以制造出容量很大但很慢的存儲器,但不可能兩邊的好處都占著,不可能制造出訪問速度又快容量又大的存儲器。因此,現代計算機都把存儲器分成若干級,稱為Memory Hierarchy,按照離CPU由近到遠的順序依次是CPU寄存器、Cache、內存、硬盤,越靠近CPU的存儲器容量越小但訪問速度越快,下圖給出了各種存儲器的容量和訪問速度的典型值。 **圖?17.8.?Memory Hierarchy** ![Memory Hierarchy](https://box.kancloud.cn/2016-04-02_56ff80d41090b.png) **表?17.1.?Memory Hierarchy** | 存儲器類型 | 位于哪里 | 存儲容量 | 半導體工藝 | 訪問時間 | 如何訪問 | | --- | --- | --- | --- | --- | --- | | CPU寄存器 | 位于CPU執行單元中。 | CPU寄存器通常只有幾個到幾十個,每個寄存器的容量取決于CPU的字長,所以一共只有幾十到幾百字節。 | “寄存器”這個名字就是一種數字電路的名字,它由一組觸發器(Flip-flop)組成,每個觸發器保存一個Bit的數據,可以做存取和移位等操作。計算機掉電時寄存器中保存的數據會丟失。 | 寄存器是訪問速度最快的存儲器,典型的訪問時間是幾納秒。 | 使用哪個寄存器,如何使用寄存器,這些都是由指令決定的。 | | Cache | 和MMU一樣位于CPU核中。 | Cache通常分為幾級,最典型的是如上圖所示的兩級Cache,一級Cache更靠近CPU執行單元,二級Cache更靠近物理內存,通常一級Cache有幾十到幾百KB,二級Cache有幾百KB到幾MB。 | Cache和內存都是由RAM(Random Access Memory)組成的,可以根據地址隨機訪問,計算機掉電時RAM中保存的數據會丟失。不同的是,Cache通常由SRAM(Static RAM,靜態RAM)組成,而內存通常由DRAM(Dynamic RAM,動態RAM)組成。DRAM電路比SRAM簡單,存儲容量可以做得更大,但DRAM的訪問速度比SRAM慢。 | 典型的訪問時間是幾十納秒。 | Cache緩存最近訪問過的內存數據,由于Cache的訪問速度是內存的幾十倍,所以有效利用Cache可以大大提高計算機的整體性能。一級Cache是這樣工作的:CPU執行單元要訪問內存時首先發出VA,Cache利用VA查找相應的數據有沒有被緩存,如果Cache中有就不需要訪問物理內存了,如果是讀操作就直接將Cache中的數據傳給CPU寄存器,如果是寫操作就直接改寫到Cache中;如果Cache沒有緩存該數據,就去物理內存中取數據,但并不是要哪個字節就取哪個字節,而是把相鄰的幾十個字節都取上來緩存著,以備下次用到,這稱為一個Cache Line,典型的Cache Line大小是32~256字節。如果計算機還配置了二級緩存,則在訪問物理內存之前先用PA去二級緩存中查找。一級緩存是用VA尋址的,二級緩存是用PA尋址的,這是它們的區別。Cache所做的工作是由硬件自動完成的,而不是像寄存器一樣由指令決定先做什么后做什么。 | | 內存 | 位于CPU外的芯片,與CPU通過地址和數據總線相連。 | 典型的存儲容量是幾百MB到幾GB。 | 由DRAM組成,詳見上面關于Cache的說明。 | 典型的訪問時間是幾百納秒。 | 內存是通過地址來訪問的,在啟用MMU的情況下,程序指令中的地址是VA,而訪問內存用的是PA,它們之間的映射關系由操作系統維護。 | | 硬盤 | 位于設備總線上,并不直接和CPU相連,CPU通過設備總線的控制器訪問硬盤。 | 典型的存儲容量是幾百GB到幾TB。 | 硬盤由磁性介質和磁頭組成,訪問硬盤時存在機械運動,磁頭要移動,磁性介質要旋轉,機械運動的速度很難提高到電子的速度,所以訪問速度很受限制。保存在硬盤上的數據掉電后不會丟失。 | 典型的訪問時間是幾毫秒,是寄存器訪問時間的10<sup>6</sup>倍。 | 由驅動程序操作設備總線控制器去訪問。由于硬盤的訪問速度較慢,操作系統通常一次從硬盤上讀幾個頁面到內存中緩存起來,如果這幾個頁面后來都被程序訪問到了,那么這一次讀硬盤的時間就可以分攤(Amortize)給程序的多次訪問了。 | 對這個表格總結如下。 * 寄存器、Cache和內存中的數據都是掉電丟失的,這稱為易失性存儲器(Volatile Memory),與之相對的,硬盤是一種非易失性存儲器(Non-volatile Memory)。 * 除了訪問寄存器由程序指令直接控制之外,訪問其它存儲器都不是由指令直接控制的,有些是硬件自動完成的,有些是操作系統配合硬件完成的。 * Cache從內存取數據時會預取一個Cache Line緩存起來,操作系統從硬盤讀數據時會預讀幾個頁面緩存起來,都是希望這些數據以后會被程序訪問到。大多數程序的行為都具有局部性(Locality)的特點:它們會花費大量的時間反復執行一小段代碼(例如循環),或者反復訪問一個很小的地址范圍中的數據(例如訪問一個數組)。所以預讀緩存的辦法是很有效的:CPU取一條指令,我把和它相鄰的指令也都緩存起來,CPU很可能馬上就會取到;CPU訪問一個數據,我把和它相鄰的數據也都緩存起來,CPU很可能馬上就會訪問到。設想有兩臺計算機,一臺有256KB的Cache,另一臺沒有Cache,兩臺計算機的內存都是512MB的,硬盤都是100GB的,雖然多出來256KB的Cache與內存、硬盤的容量相比微不足道,但訪問Cache比訪問內存、硬盤快幾個數量級,由于局部性原理,CPU大部分時間是在和Cache打交道,有Cache的計算機明顯會快很多。高速存儲器的容量只能做得很小,卻能顯著提升計算機的性能,這就是Memory Hierarchy的意義所在。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看