【深入理解计算机系统 01】计算机系统漫游
01計算機系統漫游
本書的主要作用:幫助我們了解當我們在系統上執行hello程序時,系統發生了什么以及為什么會這樣
#include <stdio.h>int main() {printf("hello, world\n");return 0; }信息是「位+上下文」
hello的生命周期從最初的源程序(源文件) 開始,是一個名為hello.c的文本文件
-
源程序實際上就是一個由值0和1組成的位(也稱為比特)序列
-
8個位被組織為一組,稱為字節 ,每個字節表示程序中的某些文本字符
-
例如,ASCII標準使用一個唯一的單字節大小的整數值表示每個字符
hello.c以字節序列的方式存儲在文件當中,每一個字節都具有一個整數值
-
例如,# 對應的整數為35,即0010 0011
-
例如,i對應的整數為105,即0110 1001
-
例如,\n對應的整數為110,每一行結尾都具有一個以表示換行
-
例如,SP對應的整數為32,有空格的地方就具有它
計算機系統中的所有信息,都是由一串比特表示的,并通過上下文進行區分
-
一個同樣的字節序列,可能表示一個整數、浮點數、字符串或者機器指令
-
數字的機器表示方式與實際的整數和實數不同,它們是對真值的有限近似
程序被其他程序翻譯成不同的格式
hello程序從C語言開始,是適合人類閱讀的方式,但最終要化為一系列低級機器語言指令,
-
這些指令按照一種稱為可執行目標程序的格式進行打包
-
打包完成以二進制磁盤文件的形式進行存儲,目標程序也稱為可執行目標文件
-
Unix系統上,整個過程的轉化由編譯器驅動程序完成
上述過程對應的指令為
gcc -o hello hello.c整個過程中,由GCC完成將源文件hello.c翻譯為可執行文件hello
翻譯的過程可以劃分為四個階段,對應執行的程序如下所示,四者構成了編譯系統
-
預處理器(cpp)
-
根據以字符#開頭的命令,修改原始程序
-
例如根據#include <stdio.h>讀取系統頭文件stdio.h的內容,并插入程序中
-
最終的結果以.i作為文件擴展名
-
-
編譯器(ccl)
-
編譯器將文本文件hello.i翻譯為文本文件hello.s,包含一個匯編語言程序
-
該程序包含函數main的定義,其中的每條語句都以一種文本格式描述了一條低級機器語言指令
-
-
匯編器(as)
-
將hello.s翻譯成機器語言指令,并打包成可重定位目標程序 ,保存在hello.o
-
該階段保存的文件是二進制文件,用本文編輯器打開是亂碼
-
-
鏈接器(ld)
-
hello程序調用了printf函數,是標準C庫中的函數,存在一個名為printf.o的單獨編譯完成的目標文件當中
-
該文件需要合并到hello.o程序中,合并完成得到hello的可執行目標文件
-
可執行目標文件可以被加載到內存當中,由系統執行
-
處理器讀并解釋存儲在內存中的指令
hello.c源程序被編譯系統翻譯為可執行目標文件hello,并存放在磁盤上。
如果是在Unix系統上想要運行這個程序,當需要將文件名輸入到shell的應用程序當中
shell是一個命令行解釋器,輸出一個提示符,等待輸入一個命令行,然后執行這個命令,執行完畢之后繼續輸出一個提示符,等待下一個輸入的命令
系統的硬件組成
總線
總線是貫穿整個系統的一組電子管道,攜帶信息字節并在各個部件之間傳遞
總線被設計為傳送定長的字節塊,也就是字(word),64位系統為8個字節,32位系統為4個字節
I/O設備
系統與外部世界的聯系通道
例如鍵盤、鼠標、顯示器、磁盤等,通過控制器或適配器與I/O總線相連接。
控制器與適配器的差別在于封裝方式,功能都是在I/O設備和I/O總線之間傳遞信息
主存
臨時存儲設備,在處理器執行程序的時候,用來存放程序和程序處理的數據
邏輯上即為一個線性的字節數組,每個字節都有其唯一的地址(數組索引),從零開始
處理器
解釋(執行)存儲在主存中指令的引擎
核心是一個大小為一個字的寄存器,稱為程序計數器(PC),在任何時候都指向主存中的某條及其語言指令(即含有該指令的地址)
從系統上電開始,處理器一直在執行PC所指向的指令,再更新PC,指向下一條指令
運行hello程序
shell 是什么?shell 是一個命令解釋程序,如果命令行的第一個單詞不是內置的 shell 命令,shell 就會對這個文件進行加載并運行。此處,shell 加載并且運行 hello 程序,屏幕上顯示 “Hello World” 內容,hello 程序運行結束并退出,shell 繼續等待下一個命令的輸入。
在 shell 中輸入./hello之后,會將其逐一讀入寄存器,處理器會將其再放到內存當中。當按下回車之后,shell 程序就知道我們已經完成了命令的輸入, 然后執行一系列的指令來加載可執行文件 hello
這些指令將 hello 目標文件中的代碼和數據從磁盤復制到主存,數據就是我們要顯示輸出的”Hello World\n” ,這個復制的過程將利用 DMA(Direct Memory Access) 技術,數據可以不經過處理器,從磁盤直接到達內存。
當可執行文件 hello 中的代碼和數據都加載到主存之后,處理器就開始執行 hello 程序的 main 程序中的機器語言指令,這些指令將需要顯示的字符串從主存復制到寄存器上,最終顯示在屏幕上
高速緩存至關重要
前面的三個步驟可以看到,系統進行了大量「復制」的操作,從一個地方移動到另一個地方,這些在程序設計角度來說都是開銷,要讓復制操作盡可能快完成
機械原理說明:
較大的存儲設備要比較小的存儲設備運行地慢
高速設備的制造成本要比低速設備要高
例如,處理器從磁盤上讀取一個字的時間可能比從主存中讀取的時間要大1000萬倍。同樣寄存器和主存之間的差距也非常大,處理器從寄存器中讀取文件速度也比主存要快100倍
-
處理器與主存之間的差距在持續增大
-
加快處理器運行速度比加快主存運行速度要容易和便宜
為了處理處理器與主存之間的差異,引入了高速緩存存儲器,存放處理器近期可能會需要的信息,作為暫時的集結區域
通過讓高速緩存里存放可能經常訪問的數據,大部分的內存操作都能在高速緩存當中完成
存儲設備形成層次結構
在處理器和一個較大較慢的設備(例如主存)之前插入一個更小更快的存儲設備(高速緩存)成為一個普遍的概念
每個計算機系統中的存儲設備都被組織成一個存儲器層次結構
存儲器層次結構的主要思想:上一層的存儲器作為低一層存儲器的高速緩存
操作系統管理硬件
在使用 shell 程序和 hello 程序時候,程序都不是直接訪問鍵盤、顯示器、磁盤或者主存
操作系統是應用程序和硬件之間的一層軟件,完成兩個基本功能
防止硬件被失控的應用程序濫用
向應用程序提供簡單一致的機制來控制復雜而又通常大不相同的低級硬件設備
操作系統的抽象
文件是對I/O設備的抽象
虛擬內存是對主存和磁盤I/O設備的抽象
進程是對處理器、主存和I/O設備的抽象
進程
進程是操作系統對一個正在運行的程序的一種抽象,在一個系統上可以同時運行多個進程,每個進程都好像是在獨立地使用硬件。
并發運行,是指一個進程的指令和另一個進程的指令是交錯執行的。
一個CPU并發執行多個進程,實際上是通過在處理在進程間切換來實現的,實現這種交錯執行的機制為上下文切換
線程
一個進程可以由多個線程組成,每個線程都運行在進程的上下文中,共享同樣的代碼和全局數據。多線程比多進程之間更容易共享數據。
虛擬內存
為每個進程提供了一個假象,級每個進程都在獨占地使用主存。每個進程看到的內存都是一致的,稱為虛擬地址空間。例如 Linux 虛擬地址空間
-
程序代碼和數據
-
堆
運行時動態地擴展和收縮(調用malloc和free這樣的C標準庫)
-
共享庫
存放C標準庫和數學庫等共享庫
-
棧
編譯器用它來實現函數調用,可以動態擴展和收縮,每調用一個函數,棧就會增長,每返回一個函數,棧就會收縮
-
內核虛擬內存
為內核保留,不允許程序讀寫或調用內核代碼定義的函數,必須調用內核來執行
文件
文件就是字節序列。每個I/O設備、磁盤、鍵盤、顯示器、網絡,都可以看成文件
系統的輸入輸出都是調用稱為 Unix I/O 的系統函數調用讀寫文件來實現的
文件為應用程序提供了一個統一的視圖,來看待系統中可能含有的各式各樣的I/O設備
系統之間的利用網絡通信
從一個單獨的系統來看,網絡可以視為一個I/O設備
當系統從主存復制一串字節到網絡適配器時,數據流經過網絡到達另一臺機器;同樣的,系統可以讀取從其他機器發送來的數據,并復制到自己的主存
重要主題
系統不僅僅是硬件,系統是硬件和系統軟件互相交織的集合體
Amdahl定律
當對系統的某個部分加速時,其對系統整體性能的影響取決于該部分的重要性和加速程度
α:系統某部分執行時間與整體執行時間的比值
k:該部分性能提升的比例
Tnew?=(1?α)Told?+(αTold?)/k=Told?[(1?α)+α/k]T_{\text {new }}=(1-\alpha) T_{\text {old }}+\left(\alpha T_{\text {old }}\right) / k=T_{\text {old }}[(1-\alpha)+\alpha / k] Tnew??=(1?α)Told??+(αTold??)/k=Told??[(1?α)+α/k]
S=ToldTnew=1(1?α)+α/kS=\frac{T_{old}}{T_{new}}=\frac{1}{(1-\alpha)+\alpha / k} S=Tnew?Told??=(1?α)+α/k1?
結論:想要顯著加速整個系統,必須提升全系統中相當大的部分的速度
并發和并行
并發:同時具有多個活動的系統
并行:用并發來使系統運行地更快
線程級并發
計算機的并發是模擬出來的,通過在多個進程之間快速切換實現
可以通過單處理器系統 ,也可以通過多處理器系統 (多核或超線程)實現
指令集并行
一個處理器可以同時執行多條指令,例如流水線
單指令、多數據并行
允許一條指令產生多個可以并行的操作
計算機系統中抽象的重要性
所謂抽象,就是類似將一個函數的內部結構進行包裝后形成API對外開放,使得對內部無需了解即可使用
總結
以上是生活随笔為你收集整理的【深入理解计算机系统 01】计算机系统漫游的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Studio 2.3 打
- 下一篇: idea 手动导入 jar 包