計算機組成原理

CHIBOHANDONG發表於2023-03-08

讀書筆記,如需轉載,請註明作者:Yuloran (t.cn/EGU6c76)

前言

計算機組成原理簡介,主要摘選自唐朔飛編著的《計算機組成原理》第二版。

高階語言是如何被計算機執行的?

多層次結構的計算機系統

最初的計算機並沒有微指令系統。由於 M0、M1 都是實際存在的,為了區分,這裡分為微程式機器、傳統機器。

將高階語言翻譯成機器語言的程式叫做翻譯程式,翻譯程式分為編譯程式與解釋程式兩種型別:

  • 編譯程式:一次性將高階語言全部翻譯成機器語言
  • 解釋程式:翻譯一句執行一句,重新執行需要再次翻譯

計算機體系結構

計算機體系結構是對計算機組成的一種抽象性描述,表明計算機應包含哪些部分,如指令集、資料型別、儲存器定址技術、I/O 機理等。不同廠家的具體實現不盡相同,但是對高階語言的開發者來說,這些都是透明的,即底層實現不同不會影響到上層應用。

計算機的基本組成

馮·諾依曼計算機的特點

  • 計算機由運算器、儲存器、控制器、輸入裝置和輸出裝置組成
  • 指令由操作碼(表示操作的性質)和地址碼(表示運算元在儲存器中的位置)組成
  • 指令和資料皆用二進位制表示
  • 指令和資料以同等地位存放於儲存器內,並可按地址尋訪
  • 指令在儲存器內按順序存放,通常是順序執行的。但也可根據運算結果或設定的條件,改變執行順序
  • 機器以運算器為中心,輸入輸出裝置與儲存器之間的資料傳送通過運算器完成

計算機硬體框圖

現代計算機可認為由三大部分組成:CPU、I/O 裝置及主儲存器(Main Memory,MM),如下圖所示:

現代計算機的組成框圖

  • M⋅M(Main Memory):主儲存器,也就是常說的記憶體,與CPU直接交換資訊。此外還有輔存,如硬碟、U盤等;
  • ALU(Arithmetic Logic Unit):算數邏輯運算單元;
  • CU(Contro Unit):控制單元,解釋儲存器中的指令,併發出各種命令執行指令。

細化的計算機組成框圖

為了形象地瞭解計算機的工作過程,對現代計算機的組成框圖進行細化:

細化的計算機組成框圖

運算器

運算器最少包含 3 個暫存器(現代計算機處理器內部往往設有通用暫存器組,如 ARM Cortex-A8 處理器,有 40 個 32bit 的暫存器(32 個通用暫存器,7 個狀態暫存器,1 個程式計數器(PC,Program Counter)))和一個算數邏輯運算單元(ALU)。

  • ACC(Accumulator):累加器
  • MQ(Multiple-Quotient register):乘商暫存器
  • X:運算元暫存器

控制器

控制器是計算機的神經中樞,由它指揮各部件自動、協調地執行。具體而言:

  1. 讀取指令:命令儲存器讀出一條指令
  2. 分析指令:指出該指令需要完成什麼操作,並按定址特徵指出運算元的地址
  3. 執行指令:根據運算元所在地址以及指令的操作碼,完成某種操作

控制器由程式計數器(Program Counter,PC)、指令暫存器(Instruction Register,IR)和控制單元(CU)組成:

  • PC:存放當前欲執行指令的地址,與主存的 MAR(Memory Address Register,儲存器地址暫存器)有一條直接通路,且具備自動 +1 的功能,即可自動形成下一條指令的地址
  • IR:存放當前的指令,其內容來自主存的 MDR。IR 中的操作碼 (OP(IR)) 送至CU,用來分析指令。其地址碼 (Ad(IR)) 作為運算元的地址,送至儲存器的 MAR
  • CU:分析當前指令所需完成的操作,併發出各種微操作序列,用以控制所有被控物件

主儲存器

主儲存器(簡稱主存或記憶體)包括儲存體M、各種邏輯部件和控制電路等。儲存體由許多儲存單元組成,每個儲存單元又包含很多儲存元件,每個儲存元件可以儲存一位二進位制程式碼 0 或 1。可見一個儲存單元可儲存一串二進位制程式碼,稱這串二進位制程式碼為一個儲存字,這串二進位制程式碼的位數稱為儲存字長。儲存字長可以是 8 位、16 位、32 位等。一個儲存字可代表一個二進位制數、一串十六進位制字元、兩個 ASCII 碼或者一條指令。

每個儲存單元都有自己的地址,主存的工作方式就是按照儲存單元的地址實現對儲存字各位的讀寫,而 MAR、MDR 則用來實現按地址訪問:

  • MAR(Memory Address Register):儲存器地址暫存器,存放欲訪問的儲存單元的地址。其位數對應儲存單元的個數,如 MAR 是 32 位,則共有 2^32 = 4 * 1024 * 1024 * 1024 (1024個記作 1K) 個儲存單元
  • MDR(Memory Data Register):儲存器資料暫存器,存放從儲存體讀出的資料或準備寫入儲存體的資料(可以是程式碼,也可以是指令),其位數與儲存字長相等

當然,要想實現一個完整的讀/寫操作,CPU還需要給主存傳送各種控制訊號,如讀命令、寫命令、地址譯碼驅動訊號等。隨著硬體電路的發展,主存都製成大規模積體電路的晶片,而將MAR、MDR 整合在 CPU 晶片中。

早期計算機的儲存字長一般與機器的指令字長、資料字長相等,故訪問一次主存便可取一條指令或一個資料。隨著計算機應用範圍的不斷擴大,往往要求計算機的指令字長、資料字長是可變的。為了適應指令字長和資料字長的可變性,其長度不再由儲存字長確定,而由位元組的個數來表示。比如 4 位元組的指令字長就是 32bit,2 位元組的指令字長就是 16bit。至此,指令字長、資料字長和儲存字長不必相等,但都必須是位元組的整數倍。

下圖為32位架構的ARM儲存器組織結構,其基本資料型別有:

ARM儲存器的組織結構

  • Byte:位元組,8位;
  • HalfWord:半字,16位(半字必須與2位元組邊界對齊);
  • Word:字,32位(字必須與4位元組邊界對齊);
  • Double World(Cortex-A支援):雙字,64位(雙字必須與8位元組邊界對齊)。

計算機硬體的主要技術指標

機器字長

機器字長是指計算機進行一次整數運算所能處理的二進位制資料的位數(整數運算即定點整數運算)。因為計算機中數的表示有定點數和浮點數之分,定點數又有定點整數和定點小數之分,這裡所說的整數運算即定點整數運算。機器字長也就是運算器進行定點數運算的字長,即通用暫存器的位數

主存字長一般等於機器字長,不等的情況下,一般是主儲存器字長小於機器字長。例如機器字長是 32 位,主儲存器字長可以是 32 位,也可以是 16 位。

Windows 64 位作業系統是針對 64 位機器字長的 CPU 設計的,目前 64 位架構實現技術主要有 AMD64、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 之間的連線等。

系統匯流排

  1. 資料匯流排:雙向傳輸,其條數稱為資料匯流排寬度。資料匯流排寬度與機器字長、儲存字長有關。比如匯流排寬度是 8 位,指令字長為 16 位,那麼 CPU 取出一條指令,就需要訪問兩次主存。

  2. 地址匯流排:單向傳輸,指出資料匯流排上的源資料或目的資料所在儲存單元的地址。地址匯流排的寬度與儲存單元個數有關,比如 32 位的地址匯流排,可編址按位元組定址的儲存單元個數為 2^32 = 4 * 1024 * 1024 * 1024 ,即 4 Gigabyte。

    從儲存器讀一個字的資料時,首先由 CPU 將其地址經 MAR 通過地址匯流排送至主存,然後向主存發讀命令。主存接到讀命令後,將對應資料讀出後,經資料匯流排送至 MDR。向儲存器寫一個字的資料時,CPU 先將目的地址經 MDR 通過地址匯流排送至主存,並將資料送至 MDR,然後向主存發寫命令。主存接到寫命令後,便可以將 MDR 中的資料經資料匯流排寫至目的地址:

主存與CPU的聯絡

  1. 控制匯流排:決策匯流排使用權,用來發出各種控制訊號。I/O 裝置通過控制匯流排向 CPU 發出匯流排請求,CPU 通過控制匯流排向 I/O 裝置發出讀寫命令。

  2. 通訊匯流排:用於計算機系統之間或計算機系統與其它系統(如控制儀表、移動通訊等)之間通訊。

虛擬儲存系統

快取-主存層次和主存-輔存層次

在虛擬儲存系統中,程式設計師的程式設計地址範圍與虛擬儲存器的地址空間相對應。例如機器指令地址碼是 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原始碼情景分析 電子工業出版社 羅昇陽編著

[4] Binder系列2—Binder Driver再探 Gityuan

相關文章