馮·諾伊曼架構
Elementry先備知識
部件需要一個計畫
電腦的組成部件向你介紹了 CPU、RAM、儲存裝置和 I/O 裝置。你知道每個部件單獨做什麼。但知道部件和理解它們如何一起工作來實際執行程式是兩回事。
想想看:你的電腦有一個每秒能做數十億次計算的 CPU,以及一個裝滿程式的儲存裝置。CPU 怎麼知道要執行哪個程式?它怎麼知道下一條指令在哪裡?誰在掌控?
這一切的答案就是馮·諾伊曼架構(Von Neumann Architecture)——一種設計模型,自 1940 年代末以來幾乎所有電腦都遵循它,從第一批佔據整個房間的機器到你口袋裡的手機。
名字背後的人
這個架構以**約翰·馮·諾伊曼(John von Neumann)**命名,他是一位在 1940 年代參與最早期電腦專案的數學家。他幫助撰寫了一份描述電腦應如何組織的一般性設計報告——不是只能做一件特定工作的硬體,而是一台足夠靈活能執行你給它的任何程式的機器。
那份報告描述了我們今天仍在使用的模型。
核心概念:程式只是資料
在馮·諾伊曼的工作之前,許多計算機器被物理地接線只能執行一項特定任務。如果你想讓它們做別的事,你必須重新接線——字面上重新排列電纜和開關。它們在一個目的上速度很快,但完全不靈活。
馮·諾伊曼的關鍵洞察是:程式只是資料。指令只是數字——碰巧告訴 CPU 要做什麼的數字。由於記憶體可以保存數字,記憶體就可以保存程式。如果你把程式儲存在記憶體裡,與它處理的資料放在一起,同樣的硬體只需載入不同的程式就能做完全不同的事情。
這個概念叫做儲存程式(stored-program concept),它是電腦科學歷史上最重要的概念。
實際上它意味著:當你下載一個遊戲,你是在把一大串數字寫到你的儲存裝置上。當你啟動它,那些數字被複製到 RAM,CPU 開始讀取並對它們採取行動。CPU 沒有改變。RAM 沒有改變。只有記憶體的內容改變了。這就是為什麼一個裝置可以是遊戲主機、試算表編輯器和影片播放器——全都在同一個硬體上。
馮·諾伊曼模型的四個部分
馮·諾伊曼架構定義了四個主要元件。你已經見過它們了——現在你會看到它們如何在正式模型中組合在一起。
記憶體
在馮·諾伊曼模型中,**記憶體(memory)**同時保存兩件事:
- 程式指令——CPU 需要遵循的步驟清單
- 資料——程式正在處理的值(數字、文字、遊戲狀態,或任何它需要的東西)
兩者都住在同一個 RAM 中,僅由它們的使用方式區分。這就是儲存程式概念在實際運作中的樣子。
記憶體中的每個位置都有一個位址(address)——CPU 用來說「給我儲存在 4,200 號位置的東西」的唯一數字。把記憶體想成一長排編號的信箱。每個信箱保存一條資訊。CPU 透過指定信箱號碼來讀和寫。
CPU
在馮·諾伊曼模型中,CPU 分為兩個主要子部分:
- 控制單元(CU)(Control Unit)——驅動整個過程的部分。它從記憶體讀取指令,弄清楚它們的意思,並告訴其他所有東西要做什麼。
- 算術邏輯單元(ALU)(Arithmetic Logic Unit)——做實際數學和比較的部分:加法、減法、「這個數字比那個大嗎?」等等。
CPU 還有少數幾個微小的、超快速的記憶儲存槽,叫做暫存器(registers)。這些不是 RAM——它們直接建立在晶片本身裡,使它們比主記憶體中的任何東西都快得多。CPU 把暫存器用作即時的便條紙:「在我對那個做些事情的時候,先保存這個數字。」
有一個暫存器特別重要:程式計數器(PC)(Program Counter)。它儲存下一條要執行的指令的位址。每條指令完成後,程式計數器自動向前移動,讓 CPU 知道下一個要看哪裡。
輸入和輸出
你學過的 I/O 裝置——鍵盤、螢幕、儲存裝置、滑鼠——是電腦從外界接收資料並將結果送回去的方式。在馮·諾伊曼模型中,這些透過連接 CPU 和記憶體的同一條通訊路徑連接。
匯流排
模型中的所有東西都透過一條叫做**匯流排(bus)**的共享路徑通訊。當 CPU 想從記憶體讀取一條指令,它把位址送下匯流排,等待指令返回。當 ALU 完成計算並需要儲存結果,那個結果沿著匯流排移動到它在記憶體中的目的地。
匯流排是高速公路;CPU、記憶體和 I/O 裝置是與它相連的城市。
提取-解碼-執行週期
現在是一切清晰起來的時刻。馮·諾伊曼架構不只描述元件是什麼——它描述它們如何在一個持續的迴圈中一起運作,這個迴圈叫做提取-解碼-執行週期(fetch-decode-execute cycle)(有時也稱為指令週期)。
以下一步一步來看。
步驟 1:提取(Fetch)
控制單元查看程式計數器找到下一條指令的位址。它把那個位址沿著匯流排送到記憶體,記憶體把指令送回來。指令落在 CPU 內部的一個暫存器裡。
「從 4,200 號位址提取下一條指令。」
步驟 2:解碼(Decode)
控制單元檢查它剛提取到的指令。指令被編碼成數字,所以控制單元解碼它們:「啊,這意思是把暫存器 A 中的數字加上暫存器 B 中的數字。」
「這條指令的意思是:把暫存器 A 和暫存器 B 相加。」
步驟 3:執行(Execute)
控制單元告訴 CPU 的適當部分執行指令。在這個例子中,ALU 執行加法並把結果寫入一個暫存器。
執行後,程式計數器自動更新指向下一條指令,週期立即再次開始。
「做加法。完成。移到下一條指令。」
然後 CPU 再做整件事。又一次。又一次——每秒數十億次。
你運行過的每個程式——每個遊戲、每個網站、在背景播放的每首歌——都是由這個迴圈執行的,重複直到程式結束(或你關閉它)。
從頭到尾的一個小例子
想像一個程式,它唯一的工作是把兩個數字加在一起並顯示結果。簡化到本質,提取-解碼-執行週期是這樣處理的:
-
提取指令「把數字 5 載入暫存器 A」。
-
解碼:這意思是「把 5 放入暫存器 A」。
-
執行:暫存器 A 現在保存 5。程式計數器向前移動。
-
提取指令「把數字 3 載入暫存器 B」。
-
解碼:這意思是「把 3 放入暫存器 B」。
-
執行:暫存器 B 現在保存 3。程式計數器向前移動。
-
提取指令「把暫存器 A 和暫存器 B 相加,把結果儲存在暫存器 C 中」。
-
解碼:這意思是「ALU:計算 A + B 並把答案放入 C」。
-
執行:ALU 計算 5 + 3 = 8 並把 8 放入暫存器 C。程式計數器向前移動。
-
提取指令「把暫存器 C 送到螢幕」。
-
解碼:這意思是「把 C 的值輸出為顯示」。
-
執行:8 出現在你的螢幕上。
就這樣。三個步驟,重複四次。一個完整的程式——由同一個週期自動執行,一次一條指令。
設計的代價:馮·諾伊曼瓶頸
馮·諾伊曼架構有一個值得注意的弱點。因為指令和資料都住在同一個記憶體中,並通過同一條匯流排移動,CPU 一次只能提取一件事。如果 CPU 同時需要一條指令和一些資料,其中一個必須等待。
這個限制——匯流排成為擁塞點——被稱為馮·諾伊曼瓶頸(Von Neumann bottleneck)。隨著 CPU 在幾十年中變得越來越快,這變得越來越明顯:CPU 能夠以遠比記憶體能夠提供的更快的速度執行指令。
現代 CPU 使用幾個技巧來解決這個問題。最重要的是直接建立在 CPU 晶片中的一小塊極快的記憶體,叫做快取(cache)。快取儲存最近使用的指令和資料的副本,讓 CPU 不需要一路旅行到 RAM 就能抓取它們。
你現在還不需要詳細了解快取如何運作。重要的是,即使在今天的硬體中,馮·諾伊曼模型仍然塑造著基本設計——工程師只是在它上面添加了幾層巧妙的最佳化。
摘要
- **馮·諾伊曼架構(Von Neumann Architecture)**是幾乎每台有史以來建造的電腦所遵循的設計模型。它在 1940 年代被描述,至今仍然是現代電腦科學的基礎。
- **儲存程式(stored-program concept)**是它的核心洞察:程式只是儲存在記憶體中的資料。載入不同的程式讓同樣的硬體做完全不同的事情。
- 這個模型有四個元件:
- 記憶體(memory)——以編號位址保存程式指令和它們處理的資料。
- CPU——執行指令,分為控制單元(CU)(驅動過程)和 ALU(做數學)。
- I/O 裝置——連接電腦與外部世界。
- 匯流排(bus)——資料在元件之間移動的共享路徑。
- 在 CPU 內部,小的**暫存器(registers)**充當超快速的便條紙。程式計數器暫存器總是保存下一條指令的位址。
- CPU 在連續的提取-解碼-執行週期中運作:從記憶體提取下一條指令,解碼它的意思,執行它,然後重複——每秒數十億次。
- 馮·諾伊曼瓶頸是缺點:一條共享的匯流排意味著指令和資料不能同時移動。現代 CPU 用建立在晶片中的**快取(cache)**記憶體來減少影響。