讀書筆記,如需轉載,請註明做者:Yuloran (t.cn/EGU6c76)git
計算機組成原理簡介,主要摘選自唐朔飛編著的《計算機組成原理》第二版。程序員
最初的計算機並無微指令系統。因爲 M0、M1 都是實際存在的,爲了區分,這裏分爲微程序機器、傳統機器。編程
將高級語言翻譯成機器語言的程序叫作翻譯程序,翻譯程序分爲編譯程序與解釋程序兩種類型:緩存
計算機體系結構是對計算機組成的一種抽象性描述,代表計算機應包含哪些部分,如指令集、數據類型、存儲器尋址技術、I/O 機理等。不一樣廠家的具體實現不盡相同,可是對高級語言的開發者來講,這些都是透明的,即底層實現不一樣不會影響到上層應用。架構
現代計算機可認爲由三大部分組成:CPU、I/O 設備及主存儲器(Main Memory,MM),以下圖所示:併發
爲了形象地瞭解計算機的工做過程,對現代計算機的組成框圖進行細化:框架
運算器最少包含 3 個寄存器(現代計算機處理器內部每每設有通用寄存器組,如 ARM Cortex-A8 處理器,有 40 個 32bit 的寄存器(32 個通用寄存器,7 個狀態寄存器,1 個程序計數器(PC,Program Counter)))和一個算數邏輯運算單元(ALU)。操作系統
控制器是計算機的神經中樞,由它指揮各部件自動、協調地運行。具體而言:翻譯
控制器由程序計數器(Program Counter,PC)、指令寄存器(Instruction Register,IR)和控制單元(CU)組成:設計
主存儲器(簡稱主存或內存)包括存儲體M、各類邏輯部件和控制電路等。存儲體由許多存儲單元組成,每一個存儲單元又包含不少存儲元件,每一個存儲元件能夠存儲一位二進制代碼 0 或 1。可見一個存儲單元可存儲一串二進制代碼,稱這串二進制代碼爲一個存儲字,這串二進制代碼的位數稱爲存儲字長。存儲字長能夠是 8 位、16 位、32 位等。一個存儲字可表明一個二進制數、一串十六進制字符、兩個 ASCII 碼或者一條指令。
每一個存儲單元都有本身的地址,主存的工做方式就是按照存儲單元的地址實現對存儲字各位的讀寫,而 MAR、MDR 則用來實現按地址訪問:
固然,要想實現一個完整的讀/寫操做,CPU還須要給主存發送各類控制信號,如讀命令、寫命令、地址譯碼驅動信號等。隨着硬件電路的發展,主存都製成大規模集成電路的芯片,而將MAR、MDR 集成在 CPU 芯片中。
早期計算機的存儲字長通常與機器的指令字長、數據字長相等,故訪問一次主存即可取一條指令或一個數據。隨着計算機應用範圍的不斷擴大,每每要求計算機的指令字長、數據字長是可變的。爲了適應指令字長和數據字長的可變性,其長度再也不由存儲字長肯定,而由字節的個數來表示。好比 4 字節的指令字長就是 32bit,2 字節的指令字長就是 16bit。至此,指令字長、數據字長和存儲字長沒必要相等,但都必須是字節的整數倍。
下圖爲32位架構的ARM存儲器組織結構,其基本數據類型有:
機器字長是指計算機進行一次整數運算所能處理的二進制數據的位數(整數運算即定點整數運算)。由於計算機中數的表示有定點數和浮點數之分,定點數又有定點整數和定點小數之分,這裏所說的整數運算即定點整數運算。機器字長也就是運算器進行定點數運算的字長,即通用寄存器的位數。
主存字長通常等於機器字長,不等的狀況下,通常是主存儲器字長小於機器字長。例如機器字長是 32 位,主存儲器字長能夠是 32 位,也能夠是 16 位。
Windows 64 位操做系統是針對 64 位機器字長的 CPU 設計的,目前 64 位架構實現技術主要有 AMD6四、Intel EM64T 等。
主存容量 = 存儲單元數 * 存儲字長
好比,若 MAR 是 32 位,則存儲單元個數爲: 2^32 = 4 * 1024 * 1024 * 1024個。若存儲字長爲 8 位,則存儲容量 = 4 * 1024 * 1024 * 1024 * 8 bit,即 4G(4 Gigabyte) 。
單位時間內執行的指令平均條數,單位 MIPS(Million Instruction Per Second)。
同一時刻只能有一個部件向總線發送信息,可是能夠有多個部件接受信息,由於總線是各部件共享的。
芯片內部的連線,好比寄存器之間、寄存器與 ALU 之間的連線等。
數據總線:雙向傳輸,其條數稱爲數據總線寬度。數據總線寬度與機器字長、存儲字長有關。好比總線寬度是 8 位,指令字長爲 16 位,那麼 CPU 取出一條指令,就須要訪問兩次主存。
地址總線:單向傳輸,指出數據總線上的源數據或目的數據所在存儲單元的地址。地址總線的寬度與存儲單元個數有關,好比 32 位的地址總線,可編址按字節尋址的存儲單元個數爲 2^32 = 4 * 1024 * 1024 * 1024 ,即 4 Gigabyte。
從存儲器讀一個字的數據時,首先由 CPU 將其地址經 MAR 經過地址總線送至主存,而後向主存發讀命令。主存接到讀命令後,將對應數據讀出後,經數據總線送至 MDR。向存儲器寫一個字的數據時,CPU 先將目的地址經 MDR 經過地址總線送至主存,並將數據送至 MDR,而後向主存發寫命令。主存接到寫命令後,即可以將 MDR 中的數據經數據總線寫至目的地址:
控制總線:決策總線使用權,用來發出各類控制信號。I/O 設備經過控制總線向 CPU 發出總線請求,CPU 經過控制總線向 I/O 設備發出讀寫命令。
通訊總線:用於計算機系統之間或計算機系統與其它系統(如控制儀表、移動通信等)之間通訊。
在虛擬存儲系統中,程序員的編程地址範圍與虛擬存儲器的地址空間相對應。例如機器指令地址碼是 32 位,那麼虛擬存儲器的存儲單元個數可達 2^32 = 4 * 1024 * 1024 * 1024 個,若存儲字長爲 8 位,則存儲容量爲 4 Gegabyte,這可能比主存實際的存儲單元個數多得多。這類指令地址碼稱爲虛擬地址或邏輯地址,主存的實際地址稱爲物理地址。虛擬地址到物理地址的轉換由操做系統負責實現,好比 Windows 操做系統經過頁目和頁表來實現虛擬地址到物理地址的轉換。若虛擬地址指向的內容在主存,則可被 CPU 直接使用,不然必須先傳到主存,而後才能被 CPU 訪問。
閱讀《Android源代碼情景分析》Binder 進程間通訊系統一章,老羅(羅昇陽,原書做者)列舉 Google 開發Binder 做爲 IPC 框架緣由時說:「與傳統的進程間通訊機制相比,Binder 進程間通訊機制在進程間傳輸數據時,只須要執行一次拷貝操做,所以,它不只提升了效率,並且節省了內存空間」,對「只拷貝一次」有點疑惑:「Pipe 不也是隻有一次嗎?」(犯二了,實際上是兩次)
以 Pipe(無名管道,用於具備親緣關係的進程間通訊,好比父子進程、兄弟進程)爲例,進程 A 向進程 B 發送數據,須要先將進程 A 用戶空間中的數據拷貝至管道(在內核空間中),而後進程 B 再從管道中將數據拷貝至本身的用戶空間,數據確實拷貝了兩次。而 Binder 機制下,因爲虛擬進程地址空間(vm_area_struct)和虛擬內核地址空間(vm_struct)都映射到同一塊物理內存空間,當 Client 端與 Server 端發送數據時,Client(做爲數據發送端)先從本身的進程空間把 IPC 通訊數據 copy_from_user 拷貝到內核空間,而 Server 端(做爲數據接收端)與內核共享數據,再也不須要拷貝數據,而是經過內存地址空間的偏移量,便可獲悉內存地址,整個過程只發生一次內存拷貝。效率最高的當屬共享內存了,無需任何拷貝便可訪問,只是須要結合信號量來進行信息同步。
一不當心就鑽了牛角尖,爲了搞清爲何 32位 CPU 最大尋址空間是 4G 和 Linux 每一個進程獨佔 3G 用戶空間的問題,把計算機組成原理又翻出來挑着看了一遍。
寫文章仍是挺累的,哪怕只是一篇總結(頸椎徹底扛不住)。不過有第一篇,就會有第二篇。之前看過不少文章,都沒有總結記錄,時間長了,全忘了。。。
[1] 計算機組成原理 高等教育出版社 2000-7 唐朔飛編著
[2] ARM嵌入式體系結構與接口技術 人民郵電出版社 2013-9 楊勝利 劉洪濤編著
[3] Android源代碼情景分析 電子工業出版社 羅昇陽編著