overview
contents
show-all
home
#+TITLE: 構架 / architecture
#+AUTHOR: 謝宇恆 / XIE Yuheng
* 費恩曼的比喻
** 來源
* 本節內容來自 費恩曼 關於計算機架的演講
原始演講的視頻 :
><><>< computers-from-the-inside-out.mov
* 我看見 費恩曼 (richard feynman)
用一個比喻來 介紹電子計算機的構架
我覺得非常有趣
所以
我們嘗試來重新敘述
並且仔細觀察一下這個比喻
* 費恩曼 有一系列的關於
heuristic 和 idiosyncratic thinking
的見解
我認爲 其中的很多觀點都非常值得我們學習
** 正名
* 計算機的形態各式各樣
多因其輸入輸出設備不同而產生
對輸入和輸出設備的設計和想像可以天馬行空
* 輸入過程和輸出過程之間的是計算過程
各種需要被輸入的信息
被輸入設備數字化
然後傳遞給計算機去計算
所得到的數字化的結果
被輸出設備轉化成需要被輸出的信息
#+begin_src return-stack
(天馬行空的輸入)
[ 數字化的信息 ]
(((處理)))
[ 數字化的結果 ]
(天馬行空的輸出)
#+end_src
* 而當談論計算機的構架時
我們談論的重點就是中間這個計算部分
而不是 計算機外觀
也不是 計算機獲取輸入信息的方式
也不是 計算機展示輸出信息的方式
如果把計算機比作人的話
我們只講這個人用以思考的器官
即他的大腦
** 檔案館
* 檔案館有很多抽屜
每個抽屜上有一個地址
每個抽屜裏可以存放多張卡片
** 檔案館員工一名
* 給這個員工配備了一個黑板
用於計算時打草稿
** 推銷員的卡片
* 有一些抽屜用來存放 公司的推銷員的卡片
每個銷售員一個抽屜
* 每個銷售員每個月新增一張卡片
* 卡片上記錄
1. 名字
2. 地址
3. 固定工資
4. 提成比率
5. 銷售額
** 合計支付金額
* 比如老版來給檔案館員工說
合計本月應該支付給廣州的銷售員的金額
我們來構擬一下 檔案館員工 的工作流程
* 何如
*** 答
* 找黑板上的一塊地方 寫上零
作爲累加器
* 遍歷整個檔案館中
存放公司的推銷員的卡片的所有抽屜
算出需要支付的薪金
薪金 = 固定工資 + (提成比率 * 銷售額)
** 檔案館員工的基本能力
* 在我們所構擬的檔案館員工的工作流程中
我們想當然地假設了檔案館員工的很多能力
我們來仔細觀察一下 都有那些能力
* 何如
*** 答
1. 存取卡片
2. 寫改黑板
3. 加法
4. 乘法
** 比喻之形成
* 何爲 費恩曼的比喻
*** 答
* 比
| 能比 | 所比 |
|----------------+--------------------|
| 檔案館 | 一級存儲器 (內存) |
| 檔案館員工一名 | 中央處理器 (CPU) |
| 黑板 | 中央處理器的寄存器 |
* 他所能做的操作是
1. 從某個抽屜中拿出一張卡來
把其中的值記錄在草稿黑板上
#+begin_src fasm
mov rax, [address]
=對應於=>
mov 黑板上的某個位置, [某個抽屜中的某張卡片]
#+end_src
2. 用草稿紙做計算
#+begin_src fasm
在黑板上做計算
add rbx, rcx
add rbx, 8
參照抽屜中的卡片做計算
add rbx, [address]
#+end_src
3. 把草稿紙上的值寫回到某個抽屜中的卡片上
#+begin_src fasm
mov [address], rax
=對應於=>
mov [某個抽屜中的某張卡片], 黑板上的某個位置
#+end_src
** 小笨
* 現在有一個新的
拿卡片 和 放卡片 的速度非常快的人
[經過測試 其速度是老員工的五倍]
前來應聘 檔案館員工這個職位
* 但是在面試的時候我們發現他不會做乘法
我們很想錄用他
畢竟他的速度非常快
* 我想要教會他做乘法
何如
*** 答
* 所以我們這樣教他來做乘法
每當他發現需要將兩個數相稱的時候
[也許是看到了乘法符號 "*" 也許是 "mul"]
比如
| 16 * 32 | 中綴表達式 (infix-notation) |
| (* 16 32) | 前綴表達式 (prefix-notation) |
| 16 32 * | 後綴表達式 (postfix-notation) |
表達形式並不重要 只要讓他能看懂就行
* 我們告訴他先去看最後兩個數字 "6" 和 "2"
然後去一個 名字叫 "乘法表" 的抽屜裏
找第 62 張卡片
上面寫着 "12"
顯然
只要告訴他具體的步驟
之後他就能按照我們在草稿紙上做乘法的樣子
去在黑板上做乘法了
* 也就是說我們發現不必讓他記住 乘法表
只要讓他知道
上哪裏去找乘法表中的結果 就行了
只要讓他能夠
在看到乘法符號的時候
能夠按照一系列具體的指令
存取卡片 並 改寫黑板 就行了
當然最後他是用加法把乘法的結構算出來的
* 更重要的一點在於
我們甚至不必告訴他
我們嘗試教他做的 是一種叫做乘法的運算
我們只要讓他能夠
在看到某個代表指令的符號的時候
能夠知道應該作出哪樣的一系列操作
而這一系列操作正是他所擅長的
即存取卡片
還有 改寫黑板上的某個地方的值
僅此而已
* 也就是說我們可以把乘法定義成
一系列的簡單的[愚蠢的]存取卡片的操作
這一系列操作的特點是
它們遵循非常嚴格的規則
* 你發現了
需要記憶的東西[比如乘法表]根本不是問題
因爲我們的檔案館有很多檔案櫃呢
而這些檔案櫃的目的正是用來幫助我們記錄東西的
[也就是內存 也就是電腦的記憶單元]
** 中笨
* 現在我們又有一個應聘者
他的速度更快 但是他不會加法
* 何如
*** 答
* 我們只要加一個 加法表就行了
** 笨笨
* 然後又有一個應聘者
他的速度更快 但是他不知道什麼是數字
但是他能比較兩個東西是否相同
也就是說
他甚至不必知道自己所處理的是數字
* 何如
*** 答
* 那麼他的如何獲得我們的指令呢
指令也寫到一系列卡片上就行了
我們只要讓他
按照我們安排好順序的一系列卡片上的指令做事情就行了
* 那麼現在他的所需要有的能力是什麼
* 他需要能夠把特殊樣子的卡片和某個指令[某個操作]想對應
* 他還需要能夠知道指令的順序
也就是說知道下一個指令的位置就行了
只要黑板上的一個地方
寫下用來記錄下一個指令的位置的數字 就行了
每次開始執行一個指令的時候
他先給這個卡片上的數字加一
以讓這個數字所記錄的地址變成下一個指令的地址
* 你可以發現
這個笨笨之笨 猶如機器
而正因如此
我們其實已經能夠把這些工作機械化了
* 你可以發現
如果你能記住很多東西
那可並不代表你很聰明
反而很有可能代表你很笨
笨蛋裏最極端者
就要屬電腦了
** 大笨
* 最後的大笨
所能比較的只是兩個信號
這兩種信號的屬性並不重要
可以是 白點 與 黑點
可以是 0 與 1
可以是 高頻電磁波 與 低頻電磁波
可以是 高電壓 與 低電壓
每一個信號的不同就是一個 bit
[我們用 bit 這個單位來度量信息]
* 何如
*** 答
* 解決方案是
所有的東西都必須用大笨所能識別的信號來編碼
* 因爲大笨太笨了
所以我們先給太笨製作一個抽屜的地圖
用八個抽屜來舉個例子
我們發現用三個 bit 就能編碼這八個抽屜
| 白 白 白 |
| 白 白 黑 |
| 白 黑 白 |
| 白 黑 黑 |
| 黑 白 白 |
| 黑 白 黑 |
| 黑 黑 白 |
| 黑 黑 黑 |
* 然後我們可以給他設計一個 "找抽屜的行動準則"
這裏需要他的一個能力
即 能夠找到某些抽屜的中間的一個抽屜 就行了
* 把 白點 與 黑點
換成 0 與 1
我們發現我們其實還是在使用數字來給抽屜編碼
只不過使用的是二進制的數字而已
| 白 白 白 | 0 0 0 |
| 白 白 黑 | 0 0 1 |
| 白 黑 白 | 0 1 0 |
| 白 黑 黑 | 0 1 1 |
| 黑 白 白 | 1 0 0 |
| 黑 白 黑 | 1 0 1 |
| 黑 黑 白 | 1 1 0 |
| 黑 黑 黑 | 1 1 1 |
* 你可以發現數字的集合的重要特點就是其序關係
| 白 白 白 | 0 0 0 | 000 | 0 |
| 白 白 黑 | 0 0 1 | 001 | 1 |
| 白 黑 白 | 0 1 0 | 010 | 2 |
| 白 黑 黑 | 0 1 1 | 011 | 3 |
| 黑 白 白 | 1 0 0 | 100 | 4 |
| 黑 白 黑 | 1 0 1 | 101 | 5 |
| 黑 黑 白 | 1 1 0 | 110 | 6 |
| 黑 黑 黑 | 1 1 1 | 111 | 7 |
這種序關係其實是自然數免費送給我們的
[副產品 (byproduct)]
我們並不一定需要
例如
可以不用數字的方法是
就像給人起名字一樣 去給抽屜起名字
一羣人他們每個人的名字都不同
這種編碼能夠區分每一個人
但是人和人之間 並沒有序關係
* 序關係 是用 後繼關係 來定義的
後繼關係 比 序關係 更簡單
後繼關係 是下圖中的 有向邊
序關係 是下圖中的 有向路
#+begin_src return-stack
(0) --> (1) --> (2) --> (3) --> (4) --> > > >
#+end_src
* 後繼關係 通常被作爲基本公理 來討論自然數的性質
比如
1. 關於 具有序關係的集合 的命題
通常要用 數學歸納法 來證明
而數學歸納法 就是 後繼關係 的體現
2. 加法 乘法 可以用 後繼關係 來定義
這種定義很適合與用於證明加法乘法某些一般性質
比如 交換律 和 結合律
* 而對 加法 乘法 等等運算的實際進行
不是利用 序關係
而是利用 對自然數的某種特殊的編碼來實現的
| 非進位制 | 結繩計數 畫正字 等等 |
| 進位制 | 二進制 十進制 等等 |
典型的計算機對加法的實際運算
就是利用數字的二進制編碼來完成的
* 把 白點 與 黑點
換成 高電流 與 低電流
你可以發現我們已經能夠把這些工作電子化了
* 甚至把這些東西量子化我們就能得到量子計算機
* 其實當我們使用匯編語言的時候
我們並不關心 底層的對構架的實現方式是什麼
而我們現在所學的
是一個比喻
是一個比較抽象模型
每當需要使用一個特殊的構架的時候
[比如 x86-64 這個構架 又比如 ARM 這個構架]
我們把這個比喻具體化就行了
* 所以我可以說
就我們學習匯編語言而言
這個[想像中的]模型已經夠用了
** 編碼
*** ASCII
* 1 byte
8 bit
256 個數字可用與編碼
其實之使用了
7 bit
128 個數字可用與編碼
* 編碼了基本的英語的大小寫字母
還有 一些基本的西方的標點符號
* http://en.wikipedia.org/wiki/ASCII
*** UTF-8
* unicode
* 與 ASCII 兼容
變長編碼
* http://en.wikipedia.org/wiki/Unicode
http://en.wikipedia.org/wiki/UTF-8
*** 圖片
* 字體
以最古老的圖形接口爲例
* 顏色
以 emacs-mode 的語法高亮中使用的顏色爲例
以 我網頁的源代碼中的 css 爲例
http://en.wikipedia.org/wiki/RGB_color_model
* 真正把這些被編碼好的圖片顯示到屏幕上去
[或者是打印 或者是投影 等等]
就涉及到了輸入與輸出了
我們將發現當使用一個操作系統的時候
跟輸入與輸出有關的細節是被操作系統來處理的
我們只要使用操作系統所提供給我們的功能就行了
** 編程
* 寫程序就是去裝填代表指令的卡片到抽屜裏
* 人們發展出了很多工具來幫助自己寫程序
比如
匯編器 編譯器 解釋器
每一個工具本身也是一個程序
** 總結
* 機器等價性
* 這就在於 什麼是計算 的問題
* 這裏形成 了一個術語叫做 Turing 等價
也就是用我們所描述的這種機器的能力
來定義什麼是計算
* 機器通用性
* 我們發現這種構架具有通用性
給抽屜中填充不同的指令卡片
我們就能讓機器完成不同的任務
* 這裏又形成了一個術語
即 這種構架被稱爲是 Von Neumann 構架
* 上面我們所描述的只是內存而已
現在我們添加一個比喻
即 地下室[磁盤]
地下室裏可以存放暫時不用的卡片
* 對比喻的批判