「練拳不練功,到老一場空」。計算機底層原理,跟上層思想緊密相連。編程
CPU
計算機最重要的核心配件,全名叫中央處理器。瀏覽器
計算機的全部「計算」都是由CPU來進行的。天然,CPU也是整臺計算機造價最昂貴的部分之一。服務器
內存
你撰寫的程序、打開的瀏覽器、運行的遊戲,都要加載到內存裏才能運行。程序讀取的數據、計算獲得的結果,也都要放在內存裏。內存越大,能加載的東西天然也就越多。網絡
主板
存放在內存裏的程序和數據,須要被CPU讀取,CPU計算完以後,還要把數據寫回內存,然而CPU不能直接插到內存上,反之亦然。架構
主板是一個有着各類各樣,有時候多達數十乃至上百個插槽的配件,咱們的CPU要插在主板上,內存也要插在主板上,主板的芯片組(Chipset)和總線(Bus)解決了CPU和內存之間如何通訊問題,芯片組控制了數據傳輸的流轉,也就是數據從哪裏到哪裏的問題。總線則是實際數據傳輸的高速公路。所以 ,總線速度(Bus Speed)決定了數據能傳輸的多快。框架
有了三大件,只要配上電源供電,計算機差很少能夠跑起來了,可是如今還缺乏各種輸入(Input)/ 輸出(Output)設備,也就是咱們常說的 I/O 設備。若是你用的是本身的我的電腦,那顯示器確定必不可少,只有有了顯示器咱們才能看到計算機輸出的各類圖像、文字,這也就是所謂的輸出設備。編程語言
顯示器、鼠標、鍵盤和硬盤這些東西並非一臺計算機必須的部分。其實只須要有 I/O 設備,能讓咱們從計算機裏輸入和輸出信息。工具
顯卡
如今,使用圖形界面操做系統的計算機,不管是 Windows、Mac OS 仍是 Linux,顯卡都是必不可少的。性能
如今的主板都帶了內置的顯卡,若是你用計算機玩遊戲,作圖形渲染或者跑深度學習應用,你多半就須要買一張單獨的顯卡,插在主板上。顯卡之因此特殊,是由於顯卡里有除了 CPU 以外的另外一個「處理器」,也就是 GPU(Graphics Processing Unit,圖形處理器),GPU 同樣能夠作各類「計算」的工做。學習
南橋
鼠標、鍵盤以及硬盤,這些都是插在主板上的,做爲外部I/O設備,它們是經過主板上的南橋(SouthBridge)芯片組,來控制和CPU之間通訊。「南橋」芯片的名字很直觀,一方面,它在主板上的位置,一般在主板的「南面」。另外一方面,它的做用就是做爲「橋」,來鏈接鼠標、鍵盤以及硬盤這些外部設備和 CPU 之間的通訊。
北橋
有了南橋,天然對應着也有「北橋」。之前主板上一般也有「北橋」芯片,用來做爲「橋」,鏈接CPU和內存、顯卡之間通訊。不過隨着時間的變遷,如今主板上的「北橋」芯片的工做,已經被移到CPU內部,全部你在主板上,已經看不到北橋芯片了。
手機裏只有SD卡這樣相似硬盤功能存儲卡插槽,並無內存插槽,CPU插槽,由於手機尺寸緣由,手機制造商門選擇把CPU、內存、網絡通訊、乃至攝像頭芯片,都封裝到一個芯片,而後再嵌入到手機主板上。這種方式SoC,也就是System on a Chip(系統芯片)。
寫智能手機上的 App,和寫我的電腦的客戶端應用彷佛沒有什麼差異,都是經過「高級語言」這樣的編程語言撰寫、編譯以後,同樣是把代碼和數據加載到內存裏來執行。這是爲何呢?由於,不管是我的電腦、服務器、智能手機,仍是 Raspberry Pi 這樣的微型卡片機,都遵循着同一個「計算機」的抽象概念。
計算機祖師爺之一馮·諾依曼(John von Neumann)提出的馮·諾依曼體系結構(Von Neumann architecture),也叫存儲程序計算機。
存儲程序計算機(可編程,可存儲)
不可編程
計算機是由各類門電路組合而成的,而後經過組裝出一個固定的電路板,來完成一個特定的計算程序。一旦須要修改功能,就要從新組裝電路。
由於程序在計算機硬件層面是「寫死」的。
程序自己是存儲在計算機內存裏,能夠經過加載不一樣的程序來解決不一樣的問題。
有「存儲程序計算機」,天然也有不能存儲程序的計算機。典型的就是早年的「Plugboard」這樣的插線板式的計算機。整個計算機就是一個巨大的插線板,經過在板子上不一樣的插頭或者接口的位置插入線路,來實現不一樣的功能。這樣的計算機天然是「可編程」的,可是編寫好的程序不能存儲下來供下一次加載使用,不得不每次要用到和當前不一樣的「程序」的時候,從新插板子,從新「編程」。
著名的Engima Machine就用到了 Plugboard 來進行「編程」
能夠看到,不管是「不可編程」仍是「不可存儲」,都會讓使用計算機效率大大降低,而這個對效率的追求,也就是「存儲程序計算機」由來。
馮祖師爺,基於當時在祕密開發的 EDVAC 寫了一篇報告First Draft of a Report on the EDVAC,描述了他心目中的一臺計算機應該長什麼樣。這篇報告在歷史上有個很特殊的簡稱,叫 First Draft,翻譯成中文,其實就是《第一份草案》。這樣,現代計算機的發展就從祖師爺寫的一份草案開始了。
首先是一個包含算術邏輯單元(Arithmetic Logic Unit,ALU)和處理寄存器(Processor Register)的處理單元,用來完成各類算術和邏輯運算,。由於它可以完成各類數據的處理或者計算工做,所以也有人把這個叫做數據通路(Datapath)或者運算器。
而後一個包含指令寄存器(Instruction Register)和程序計數器(Program Counter)的控制單元(Control Unit/CU)),用來控制程序的流程,一般就是不一樣條件下的分支和跳轉。在如今的計算機裏,上面的算術邏輯單元和這裏的控制器單元,共同組成了咱們說的 CPU。
接着是用來存儲數據(Data)和指令(Instruction)的內存,以及更大容量的外部存儲,在過去,多是磁帶、磁鼓這樣的設備,如今一般就是硬盤。
最後就是各類輸入和輸出設備,以及對應的輸入和輸出機制。咱們如今不管是使用什麼樣的計算機,其實都是和輸入輸出設備在打交道。
任何一臺計算機的任何一個部件均可以歸到運算器、控制器、存儲器、輸入設備和輸出設備中,而全部的現代計算機也是基於這個基礎架構來設計開發的。
而全部的計算機程序,也均可以抽象爲從輸入設備讀取輸入信息,經過運算器和控制器來執行存儲在存儲器裏的程序,最終把結果輸出到輸出設備中。而咱們全部撰寫的不管高級仍是低級語言的程序,也都是基於這樣一個抽象框架來進行運做的。
衡量計算性能兩個標準:響應時間和吞吐率。
響應時間
執行時間,想要提高響應時間這個性能指標,你能夠理解爲讓計算機「跑得更快」。
圖中是咱們實際系統裏性能監測工具 NewRelic 中的響應時間,表明了每一個外部的 Web 請求的執行時間。
吞吐率
吞吐率或者帶寬,想要提高這個指標,你能夠理解爲讓計算機「搬得更多」。
服務器使用的網絡帶寬,一般就是一個吞吐率性能指標
吞吐率是指咱們在必定的時間範圍內,到底能處理多少事情。
性能,定義成響應時間的倒數,就是:性能 = 1/ 響應時間。
這樣一來,響應時間越短,性能的數值就越大。一樣一個程序,在 Intel 最新的 CPU Coffee Lake 上,只須要 30s 就能運行完成,而在 5 年前 CPU Sandy Bridge 上,須要 1min 才能完成。
雖然時間是一個很天然的用來衡量性能的指標,可是用時間來衡量時,有兩個問題。
時間來衡量
第一個就是時間不「準」。若是用你本身隨便寫的一個程序,來統計程序運行的時間,每一次統計結果不會徹底同樣。有可能這一次花了 45ms,下一次變成了 53ms。
可是,計算機可能同時運行着好多個程序,CPU 實際上不停地在各個程序之間進行切換。在這些走掉的時間裏面,極可能 CPU 切換去運行別的程序了。並且,有些程序在運行的時候,可能要從網絡、硬盤去讀取數據,要等網絡和硬盤把數據讀出來,給到內存和 CPU。因此說,要想準確統計某個程序運行時間,進而去比較兩個程序的實際性能,咱們得把這些時間給刨除掉。
time 命令。它會返回三個值,第一個是 real time,也就是咱們說的 Wall Clock Time,也就是運行程序整個過程當中流逝掉的時間;第二個是 user time,也就是 CPU 在運行你的程序,在用戶態運行指令的時間;第三個是 sys time,是 CPU 在運行你的程序,在操做系統內核裏運行指令的時間。而程序實際花費的 CPU 執行時間(CPU Time),就是 user time 加上 sys time。
$ time seq 1000000 | wc -l 1000000 real 0m0.101s user 0m0.031s sys 0m0.016s
其次,即便咱們已經拿到了 CPU 時間,咱們也不必定能夠直接「比較」出兩個程序的性能差別。即便在同一臺計算機上,CPU 可能滿載運行也可能降頻運行,降頻運行的時候天然花的時間會多一些。
除了CPU以外,時間這個性能指標還受到主板,內存,這些其餘相關硬件的影響。
程序的CPU執行時間 = CPU時鐘週期數 * 時鐘週期時間
時鐘週期時間
在買電腦的時候,必定關注過 CPU 的主頻。好比我手頭的這臺電腦就是 Intel Core-i7-7700HQ 2.8GHz,這裏的 2.8GHz 就是電腦的主頻(Frequency/Clock Rate)。這個 2.8GHz,咱們能夠先粗淺地認爲,CPU 在 1 秒時間內,能夠執行的簡單指令的數量是 2.8G 條。
若是想要更準確一點描述,這個 2.8GHz 就表明,咱們 CPU 的一個「鐘錶」可以識別出來的最小的時間間隔。就像咱們掛在牆上的掛鐘,都是「滴答滴答」一秒一秒地走,因此經過牆上的掛鐘可以識別出來的最小時間單位就是秒。
而在 CPU 內部,和咱們平時戴的電子石英錶相似,有一個叫晶體振盪器(Oscillator Crystal)的東西,簡稱爲晶振。咱們把晶振當成 CPU 內部的電子錶來使用。晶振帶來的每一次「滴答」,就是時鐘週期時間。在我這個 2.8GHz 的 CPU 上,這個時鐘週期時間,就是 1/2.8G。咱們的 CPU,是按照這個「時鐘」提示的時間來進行本身的操做。主頻越高,意味着這個表走得越快,咱們的 CPU 也就「被逼」着走得越快。
超頻
這說的其實就至關於把買回來的CPU內部的種給調快了,因而CPU計算跟着這個時鐘的節奏,也就天然變快了。
固然這個快不是沒有代價的,CPU 跑得越快,散熱的壓力也就越大。就和人同樣,超過生理極限,CPU 就會崩潰了。
CPU 時鐘週期數
最簡單的提高性能方案,天然縮短時鐘週期時間,也就是提高主頻。換句話說,就是換一塊好一點的 CPU。
CPU 時鐘週期數 = 指令數×每條指令的平均時鐘週期數(Cycles Per Instruction,簡稱 CPI)
不一樣的指令須要的 Cycles 是不一樣的,加法和乘法都對應着一條 CPU 指令,可是乘法須要的 Cycles 就比加法要多,天然也就慢。
程序的 CPU 執行時間 = 指令數×CPI×Clock Cycle Time
優化
程序的 CPU 執行時間 = 指令數×CPI×Clock Cycle Time
這麼來看,若是要提高計算機的性能,咱們能夠從指令數、CPI 以及 CPU 主頻這三個地方入手。要搞定指令數或者 CPI,乍一看都不太容易。因而,研發 CPU 的硬件工程師們,從 80 年代開始,就挑上了 CPU 這個「軟柿子」。在 CPU 上多放一點晶體管,不斷提高 CPU 的時鐘頻率,這樣就能讓 CPU 變得更快,程序的執行時間就會縮短。
因而,從 1978 年 Intel 發佈的 8086 CPU 開始,計算機的主頻從 5MHz 開始,不斷提高。1980 年代中期的 80386 可以跑到 40MHz,1989 年的 486 可以跑到 100MHz,直到 2000 年的奔騰 4 處理器,主頻已經到達了 1.4GHz。而消費者也在這 20 年裏養成了「看主頻」買電腦的習慣。當時已經基本壟斷了桌面 CPU 市場的 Intel 更是誇下了海口,表示奔騰 4 所使用的 CPU 結構能夠作到 10GHz,很有一點「大力出奇跡」的意思。
奔騰 4 的 CPU 主頻歷來沒有達到過 10GHz,最終它的主頻上限定格在 3.8GHz。這還不是最糟的,更糟糕的事情是,你們發現,奔騰 4 的主頻雖然高,可是它的實際性能卻配不上一樣的主頻。想要用在筆記本上的奔騰 4 2.4GHz 處理器,其性能只和基於奔騰 3 架構的奔騰 M 1.6GHz 處理器差很少。
因而,這一次的「大力出悲劇」,不只讓 Intel 的對手 AMD 得到了喘息之機,更是表明着「主頻時代」的終結。後面幾代 Intel CPU 主頻不但沒有上升,反而降低了。到現在,2019 年的最高配置 Intel i9 CPU,主頻也只不過是 5GHz 而已。相較於 1978 年到 2000 年,這 20 年裏 300 倍的主頻提高,從 2000 年到如今的這 19 年,CPU 的主頻大概提升了 3 倍。
功耗問題
咱們的 CPU,通常都被叫做超大規模集成電路(Very-Large-Scale Integration,VLSI)。這些電路,實際上都是一個個晶體管組合而成的。CPU 在計算,其實就是讓晶體管裏面的「開關」不斷地去「打開」和「關閉」,來組合完成各類運算和功能。
想要計算得快,一方面,咱們要在 CPU 裏,一樣的面積裏面,多放一些晶體管,也就是增長密度;另外一方面,咱們要讓晶體管「打開」和「關閉」得更快一點,也就是提高主頻。而這二者,都會增長功耗,帶來耗電和散熱的問題。
所以,在 CPU 裏面,可以放下的晶體管數量和晶體管的「開關」頻率也都是有限的。
功耗 ~= 1/2 ×負載電容×電壓的平方×開關頻率×晶體管數量
「製程」工藝, 從 28nm 到 7nm,至關於晶體管自己變成了原來的 1/4 大小。
可是,功耗增長太多,就會致使 CPU 散熱跟不上,這時,咱們就須要下降電壓。這裏有一點很是關鍵,在整個功耗的公式裏面,功耗和電壓的平方是成正比的。這意味着電壓降低到原來的 1/5,整個的功耗會變成原來的 1/25。
因而,從奔騰 4 開始,Intel 意識到經過提高主頻比較「難」去實現性能提高,邊開始推出 Core Duo 這樣的多核 CPU,經過提高「吞吐率」而不是「響應時間」,來達到目的。
並行處理
阿姆達爾定律(Amdahl’s Law)。這個定律說的就是,對於一個程序進行優化以後,處理器並行運算以後效率提高的狀況。
優化後的執行時間 = 受優化影響的執行時間 / 加速倍數 + 不受影響的執行時間
參考 我的Java學習園地
《深刻淺出計算機組成原理》