電腦科班生學電腦組成原理的意義何在呢?

大家好,我是小林。

很早之前分享過我學電腦網路和作業系統的心得,詳見:怎麼學作業系統和電腦網路呀?

期間一直有不少讀者問電腦組成原理怎麼學,大部分人覺得這個學科跟硬體有關係就非常怕。

計算組成原理確實是分為兩個方向,一個是硬體電路的,一個是軟體程式的。

我自己本身是干開發的,所以我這次分享的機組資料是跟軟化程式有關的,也就是不會涉及到硬體電路的東西,即使你不會數字電路、微機原理也是可以直接學習的。

好了,不多廢話,直接開車了!


學計組有什麼用?

我猜應該很多人都有這樣的困惑,就是覺得學計組有什麼用?感覺實際工作過程中用不到,感覺理論學了個寂寞。

這個困惑很正常,因為學計組這東西主要是為了搞懂電腦是如何工作的,電腦怎麼工作的都是被前輩們實現好的,我們一般也不會參與到造電腦這種工作中。

但是學了計組後,你能看到的視角是和別人不一樣的,而這個不一樣的視角就能在一些關鍵的問題上得到突破。

我這裡舉個簡單例子,你覺得下面這兩個 for 循環哪個效率會更高呢?為什麼會更高呢?

這個問題的關鍵在於,大家知不知道 CPU Cache 這個東西。

我自己曾經在還沒有學計組的時候,只覺得存儲設備就是我們常見的記憶體和硬碟,學了後我才發現還有 CPU Cache 這個東西,而能不能充分利用到這個東西,就決定你程式的性能。

CPU Cache 是 CPU 內部的一個快取,它的讀寫速度遠高於記憶體,所以它充當記憶體的快取角色,當 CPU 要訪問的數據命中了 CPU Cache,就不用去從記憶體上找數據,就像 MySQL 和 Redis 之間的關係。

CPU Cache 一般會分為三層,分別是 L1 Cache、L2 Cache、L3 Cache ,其中 L1 Cache 和 L2 Cache 是各個 CPU 核心獨立的,剩下的 L3 Cache 是各個核心共享的。

CPU Cache 的數據是從記憶體中讀取過來的,它是以一小塊一小塊讀取數據的,而不是按照單個數組元素來讀取數據的,在 CPU Cache 中的,這樣一小塊一小塊的數據,稱為 Cache Line(快取塊)。

如果 L1 Cache Line 大小是 64 位元組,也就意味著 L1 Cache 一次載入數據的大小是 64 位元組。

比如,有一個 int array[100] 的數組,當載入 array[0] 時,由於這個數組元素的大小在記憶體只佔 4 位元組,不足 64 位元組,CPU 就會順序載入數組元素到 array[15] ,意味著 array[0]~array[15] 數組元素都會 被快取在 CPU Cache 中了,因此當下次訪問這些數組元素時,會直接從 CPU Cache 讀取,而不用再從內 存中讀取,大大提高了 CPU 讀取數據的性能。

CPU Cache 的概念簡單介紹完了,再來說說剛才的 for 循環問題。

我直接說答案:形式一 array[i][j] 執行時間比形式二 array[j][i] 快好幾倍。

之所以有這麼大的差距,是因為二維數組 array 所佔用的記憶體是連續的,比如長度 N 的指是 2 的話,那麼記憶體中的數組元素的布局順序是這樣的:

形式一用 array[i][j] 訪問數組元素的順序,正是和記憶體中數組元素存放的順序一致。當 CPU 訪問 array[0][0] 時,由於該數據不在 Cache 中,於是會「順序」把跟隨其後的 3 個元素從記憶體中載入到 CPU Cache,這樣當 CPU 訪問後面的 3 個數組元素時,就能在 CPU Cache 中成功地找到數據,這意味著快取命中率很高,快取命中的數據不需要訪問記憶體,這便大大提高了程式碼的性能。

而如果用形式二的 array[j][i] 來訪問,則訪問的順序就是:

你可以看到,訪問的方式跳躍式的,而不是順序的,那麼如果 N 的數值很大,那麼操作 array[j][i] 時,是沒辦法把 array[j+1][i] 也讀入到 CPU Cache 中的,既然 array[j+1][i] 沒有讀取到 CPU Cache,那麼就需要從記憶體讀取該數據元素了。很明顯,這種不連續性、跳躍式訪問數據元素的方式,可能不能充分利用到了 CPU Cache 的特性,從而程式碼的性能不高。

那訪問 array[0][0] 元素時,CPU 具體會一次從記憶體中載入多少元素到 CPU Cache 呢?這個問題,在前面我們也提到過,這跟 CPU Cache Line 有關,它表示 CPU Cache 一次性能載入數據的大小,可以在 Linux 里通過 coherency_line_size 配置查看 它的大小,通常是 64 個位元組。

也就是說,當 CPU 訪問記憶體數據時,如果數據不在 CPU Cache 中,則會一次性會連續載入 64 位元組大小的數據到 CPU Cache,那麼當訪問 array[0][0] 時,由於該元素不足 64 位元組,於是就會往後順序讀取 array[0][0]~array[0][15] 到 CPU Cache 中。順序訪問的 array[i][j] 因為利用了這一特點,所以就會比跳躍式訪問的 array[j][i] 要快。

因此,遇到這種遍曆數組的情況時,按照記憶體布局順序訪問,將可以有效的利用 CPU Cache 帶來的好處,這樣我們程式碼的性能就會得到很大的提升,

CPU Cache 的內容遠不止於我說的這些,還有快取一致性協議、偽共享、write through 和 write back 的方式等,這些都是非常重要的知識。

計組怎麼學?

電腦組成原理會有兩個方向深入的點,一個是面向硬體電路,一個是面向軟體開發的。

我自己本身就是個開發者,所以下面分享的學習資料都是偏向軟體開發點計組原理,對於硬體電路這塊的資料不做介紹,因此不會涉及到數字電路、微機原理等這些課程。

我也整理一套系統化學習cs的書籍,數據結構,電腦網路,資料庫,電腦組成原理,作業系統這些統統都有。

這次分享給大家,點擊獲取方式電腦必讀書籍(含下載方式)包含據結構與演算法、電腦網路、資料庫、電腦組成原理、作業系統、Java、C/C++

電腦組成原理主要有四大塊內容。

第一大塊,電腦的基本組成,主要包含:

  • 硬體設備組成:CPU、主板、記憶體、硬碟、顯示器等;
  • 馮諾依曼體系結構:運算器、控制器、存儲器、輸入設備、輸出設備;
  • 電腦性能:CPU 主頻、響應時間、吞吐率

第二塊,電腦的指令和運算,主要包含:

  • 電腦指令:機器碼(編譯 -> 彙編 -> 機器碼、指令格式和跳轉、函數調用和程式棧)、程式的編譯、鏈接、裝載和執行;
  • 電腦運算:二進位編碼(整數、反碼、補碼、浮點數、定點數)、數字電路(閘電路、加法器、乘法器);

第三塊,處理器設計,主要包含:

  • CPU:建立數據通路、面向流水線和設計、控制冒險和數據冒險、分支預測、異常和中斷、並行計算

第四塊,存儲器和 I/O 系統,主要包含:

  • 存儲器的層次結構:SRAM 存儲技術、暫存器、CPU 高速快取、記憶體、固態硬碟、機械硬碟;
  • 存儲器和 I/O 系統:虛擬記憶體、CPU和記憶體的通訊、DMA技術、訪問輸入輸出設備;
  • CPU 高速快取:局部性原理、快取一致性協議、偽共享問題、write through 和 write back;
  • 虛擬存儲:缺頁異常、TLB 加速地址轉化、MMU 虛擬地址和物理地址轉換;

其中第一、第二、第四是對開發者而言是比較重要的內容,而第三部分處理器的設計如果沒時間可以先不用去了解。

別看這些內容很多,就被嚇到了,建議你在學習電腦原理的時候,心裡要帶著一個核心的問題去學習:「我們寫的程式是如何在電腦里跑起來的?

帶著這個問題去學你就不知覺的會把知識點給串起來了,一層層的深入下去,一個知識點一個知識展開。

如果把這個問題能解釋出來,那你對電腦組成原理有了一定的認識了。

計組 – 入門學習

電腦科學速成課

先極力推薦 b 站的《電腦科學速成課》,這個課程是國外錄製的,內容真的是好,影片的動畫很精美,講課的時候不會很死板,反正就是不看後悔、相見很晚系列。

在這裡插入圖片描述在這裡插入圖片描述

對於入門電腦組成,可以先看前 10 個影片,看完這 10 個影片也就不到 2 個小時,看完前 10 個影片對電腦的工作方式就有一個基本的了解了。

看完前 10 個影片就可以開始看書了。

我也整理一套系統化學習cs的書籍,數據結構,電腦網路,資料庫,電腦組成原理,作業系統這些統統都有。

這次分享給大家,點擊獲取方式電腦必讀書籍(含下載方式)包含據結構與演算法、電腦網路、資料庫、電腦組成原理、作業系統、Java、C/C++

《電腦是怎麼樣跑起來》和《程式是怎麼跑起來的》

講真,不太建議小白一上來就看那些厚的不行的電腦組成原理的黑皮書,這些書是經典的沒錯,也正是由於它們是經典的,所以這些書的知識體系很全、很多、很厚。

但是這樣很容易讓初學者迷失在裡頭,可能剛興緻勃勃看幾十頁就放棄了,於是這些厚的不行的書就成為了你們的墊書神器知識沒學多少,頸椎病倒是治好了。

對於初學者,我推薦兩本書《電腦是怎麼樣跑起來》和《程式是怎麼跑起來的》,這兩本很薄而且圖文並茂,作者都是用大白話的方式來闡述知識,這點對初學者非常友好。

這兩本不用 1 個月就能看完,因為在看這兩本書的時候,你會看的很順暢,相比學習的心態,你更多的是會帶著「好奇心」的心態去讀。

其中《程式是怎麼跑起來的》是一個「微縮版本」的電腦組成原理,你可以只選擇看這一本,從這本書的名字也可以知道,它是從電腦是怎麼運行程式的視角來講的,然後把涉及到的電腦硬體和它們之間是如何協作的一點一點的給大家帶出來,讓大家能瞬間明白這些電腦硬體的作用。

在這裡插入圖片描述在這裡插入圖片描述

這本僅僅是入門級別,主要的作用是讓初學者明白電腦組成原理這門課是學什麼的,以及梳理主要的知識體系,用了這本書的概念後,在去深入電腦組成的時候,就不會雨里霧裡的。

《編碼》

編碼:隱匿在電腦軟硬體背後的語言》這本書也很不錯,是本科普類的書,非常適合非科班的同學,主要講是電腦工作的原理(二進位編碼、加減法運算、電腦部件、浮點數定點數、處理器等),也就是跟計組息息相關的知識,它的內容很有趣味性,並不想教科書那樣晦澀難懂,絲毫不會讓你感到生硬,讀起來很暢快。

在這裡插入圖片描述在這裡插入圖片描述

計組 – 深入學習

《電腦組成與設計:硬體 / 軟體介面》

想要深入學習電腦組成原理的同學,我首先推薦《電腦組成與設計:硬體 / 軟體介面》這本書,

這本書確實很厚,差不多 500 多頁,但是書從來沒有人規定一定要從頭讀到尾,一頁頁的讀的。重要的不是看完一本書,而是從書上學到多少,解決了什麼問題。

大家可以挑這幾個章節看,跟開發者關係比較大的章節:

  • 第一章:電腦抽象以及相關技術,這個章節主要是介紹了電腦組成的思想,可以簡單快讀看,不用重點讀;
  • 第二章:指令,大體上講的是電腦是如果識別和運行指令的,以及程式碼到指令的過程;
  • 第三章:電腦的算數運算,介紹的是電腦是如何進行加減乘除法的,以及浮點數的運算;
  • 第五章:層次化存儲,講的是電腦的存儲層次結構,而且重點講的是 CPU Cahe。

電腦組成原理影片課程

看書覺得很累,也可以結合影片一起看,這裡推薦哈工大的《電腦組成原理》影片,在 b 站就可以直接看,大家自己去搜索就可以。

在這裡插入圖片描述在這裡插入圖片描述

看書和看影片可以相互結合的,比如你看影片看了電腦指令的內容,然後你可以不用繼續往下看,可以回到一本書上,看書上對應這個章節的內容,這是個很好的學習方法,影片和書籍相輔相成。

你要是覺得哈工大的計組課程太難,你可以看王道考研的電腦組成原理的影片課程,同樣 b 站就可以看。

在這裡插入圖片描述在這裡插入圖片描述

這個影片雖然是針對考研的,但是也是可以作為學習計組的資料,講的內容不會太深,適合你快速建立電腦組成原理體系,和梳理計組知識的脈絡。

《深入理解計算系統》

另外,在推薦一本《深入理解計算系統》這本書,人稱 CSAPP。

可能大家以為這本書是講作業系統的,我最開始也以為是這樣。後面當我開始啃這本書的時候,發現我大錯特錯,它遠不止我想的那樣。

這本書是從程式設計師的角度學習電腦系統是如何工作的,通過描述程式是如何映射到電腦系統上,程式是如何執行的,以及程式效率低下的原因,這樣的方式可以讓大家能更好的知道「程式與電腦系統」的關係。

CSAPP 涵蓋的內容非常多,有電腦組成 + 作業系統 + 彙編 + C語言 + Linux系統編程,涉獵的領域比較多,是一本綜合性的書,更是一本程式設計師修鍊內功的指引書。

CSAPP 主要包括以下內容:

  • 資訊表示(如何使用二進位表示整型、浮點數等);
  • C 和彙編語言的學習(通過彙編語言更深入地理解C語言是什麼);
  • 電腦體系結構(存儲層次結構、局部性原理、處理器體系結構);
  • 編譯鏈接(C語言如何從文本變成可執行文件、靜態鏈接、動態鏈接);
  • 作業系統的使用(異常控制流、虛擬記憶體、多個系統調用介紹);
  • 網路及並發編程(並發的基本概念、網路相關的系統調用的介紹)。

你會發現有部分內容和《電腦組成與設計:硬體 / 軟體介面》這本書重合了,重合的部分就是重中之重的電腦組成原理知識了,而且內容都是差不多的,你可以看完一本書的內容,然後跳到另外一本看相同章節的內容,多本書的結合可以讓我們更加容易理解。

這兩本書有個區別:

  • 《電腦組成與設計:硬體 / 軟體介面》講的指令格式是 RISC 的;
  • 《深入理解計算系統》講的指令格式是 x86 的;

其他重合的計組知識都大同小異。

CSAPP 的影片課程是國外老師錄製的,但是在 b 站已經有好人幫我們做了中文字幕,看了這影片,相當於在國外上了一門電腦課的感覺。

B站地址://www.bilibili.com/video/BV1iW411d7hd

如果你是在校生,有了一定 C 語言基礎後,非常建議你就開始看這本書,有精力也可以做做 CSAPP 的 lab。越早開始看,你的收益就越大,因為當電腦體系搭建起來後,你後面再深入每一個課程的時候,你會發現學起來會比較輕鬆些。

對於已經工作了,但是電腦系統沒有一個清晰認識的讀者,也可以從這本書開始一點一點學起來,這本書是很厚,但是並不一定要把書完完看完,每個章節的知識點還是比較獨立的,有關硬體的章節我們可以選擇跳過。

這就是我學計組的心得啦。

沒學過計租的同學,可以找個時間補補了,提高下自己的「內功」。

干就完啦!