深入理解計算機系統讀書筆記(第一章 計算機系統漫遊)

第一章 計算機系統漫遊

本章主要從計算機系統的基本構成,很籠統抽象的講解了計算機系統的運行原理和基本概念。

1.1 信息就是位+上下文

每一段代碼在計算機中存儲的時候都是字節序列一個字節等於8位(bit),比如下代碼:
Hello.c:

#include <studio.h>

int main()
{
    printf("hello,World\n");
    return 0;
} 

這段代碼存儲在計算機中時,編碼後用字節序列來存儲代碼信息(每一種編碼方式獲得的字節序列不盡相同),例如用ASCII碼(每一個字節對應一個字符)得到的是如下序列形式:
在這裏插入圖片描述
比如一個字母i,它在計算機中存儲的字節是:105
我們在屏幕上看到的字符,在計算機中存儲的都是一字節序列存儲起來的,至於字節序列的差異是由編碼方式決定的
像這種我們可讀的代碼文件都稱爲文本文件,其他的文件都是二進制文件
計算機中存儲文件或傳輸的信息,都是對應的字節序列。區分這些序列區別的就是與這些序列的上下文,一段相同字節序列在不同的上下文中可能有不同的含義,比如它可能表示一個字符、整數、浮點、負數或是機器指令。

1.2 程序被其他程序翻譯成不同的格式

源代碼經過編譯系統的處理,就被翻譯成爲可執行的二級制文件:
在這裏插入圖片描述

  • 預處理:預處理是執行程序中的預編譯指令,還要處理代碼中的"#"開頭的命令,比如處理頭文件,會把相關頭文件包含的信息複製到本段代碼中來,形成hello.i文件
  • 編譯器:編譯器(包含一個彙編語言程序)會將hello.i文件翻譯成爲hello.s。它包含的彙編語言程序爲不同高級語言的不同編譯器提供了通用的輸出語句。
  • 彙編階段:彙編階段是將hello.s中的指令打包成爲一個可重定位目標程序hello.o,這是二進制文件。
  • 鏈接階段:連接器負責將各個部分的調用整合在一起,最終打包成爲可執行目標文件。

1.3 瞭解編譯系統如何工作是大有益處的

  • 優化程序性能
  • 理解鏈接時出現的錯誤
  • 避免安全漏洞

1.4 處理器讀並解釋存儲在內存中的指令

在這裏插入圖片描述

1.4.1 系統的硬件組成

  • 總線
    總線,負責在各個部件之間傳遞數據,被設計成爲傳送定長的字節塊,也就是字(word),現在的機器分爲32位(字長爲4字節),或者64位(字長爲8字節)
  • I/O設備
    計算機系統都是通過I/O設備與外界交互。每一個I/O設備都是通過控制器或適配器與I/O總線相連。控制器與適配器是根據集成在計算機上的方式來區分:控制器是直接集成在主板或者I/O設備本身帶有的,而適配器是插在主板卡槽上的卡,他們的功能都是在I/O設備和I/O總線之間傳遞信息
  • 主存
    從物理上來說,主存是由一組**動態隨機存取存儲器(DRAM)**芯片組成,從邏輯上來說,存儲器是一個線性的字節數組,每個字節都有其唯一的地址。一般來說,組成程序的每條機器指令都由不同數量的字節構成。
  • 處理器
    中央處理器,即CPU,簡稱處理器,處理器的核心是一個大小爲一個字(注意是字(32位或64位),不是字節)的存儲設備(寄存器)成爲程序計數器(PC),從開機開始PC就指向主存中的某條機器指令,並執行該指令,執行完成後,更新PC再繼續執行。CPU的操作圍繞着主存,寄存器文件(register file)和邏輯/算術單元(ALU)進行。寄存器文件是由單個字長的寄存器組成,每個寄存器都有唯一的名字。CPU可能會有以下操作:
    • 加載: 從主存複製一個字節或字到一個寄存器,覆蓋到寄存器中的內容
    • 存儲:從寄存器中複製一個字節或字到主存,覆蓋主存中的內容
    • 操作:把兩個寄存器中的內容複製到ALU,並進行運算,運算結果複製到一個寄存器中
    • 跳轉:從指令本身中抽取一個字,複製到PC中, 以覆蓋PC中原來值

1.4.2 運行hello程序

當你在shell窗口敲入hello命令時,計算機會將你鍵盤敲入的信息存入,CPU中的寄存器中,然後再存入主存中:
在這裏插入圖片描述
當你完成輸入時敲下回車,計算機會在磁盤上找到hello程序,並將其存入主存(利用直接存儲器技術(DMA)數據可以從磁盤直接到達主存):
在這裏插入圖片描述
主存會將讀取的hello程序的內容存入CPU的寄存器,CPU運算完成後,會將結果輸出到顯示屏上,整個順序如下:在這裏插入圖片描述

1.5 高速緩存至關重要

從上面的例子可以看出,程序的執行過程可以看出,計算機系統花費了大量的時間進行復制操作, 這些操作往往會成爲處理器運算的瓶頸,CPU運算能力提升迅速。加快CPU運算速度比加快主存的運算速度要容易和便宜得多,所以針對CPU和主存之間的差距就催生了高速緩存存儲器(cache memory.)。
處理器中的高速緩存是分級的,能力越強的CPU可能會擁有2級甚至三級緩存,這使得處理器在獲取數據時比直接從主存中獲取數據快得多。讓經常被訪問的數據常駐高速緩存中,就會成倍的提高計算機的運行速度。

1.6 存儲設備形成層次結構

在較大較慢的存儲器之上加入較小較快的存儲器的想法已成爲普遍觀念:
在這裏插入圖片描述

圖上,存儲器層次結構越往上價格越貴,速度越快。程序員可以利用對整個層次結構的理解來提高程序的運行效率。

1.7 操作系統管理硬件

在你執行程序的時候,直接提供服務的是操作系統,它使得計算機硬件有序安全的運行,操作系統有兩個基本功能:1.防止硬件被程序濫用;2.向程序提供一致的機制來控制複雜而不同計算機硬件。操作系統通常將計算機硬件抽象成爲程序中常用的概念:
文件是對I/O設備的抽象,虛擬內存是對主存和磁盤I/O設備的抽象表示,進程是對I/O設備、處理器和主存的抽象表示。
在這裏插入圖片描述

1.7.1 進程

進程是操作系統對一個正在運行的程序的抽象。一個進程的運行就像是該程序在獨佔計算機硬件資源一樣,但實際上CPU總是在不同進程之間做切換,由於運行速度太快,我們無法感知而已。操作系統實現這種交錯執行的機制成爲上下文切換,即保存進程運行的狀態和上下文,以便在下次運行該進程時,可以從原來的狀態繼續執行。

1.7.2 線程

一個進程還可以有多個線程組成,這些線程共享進程的代碼和全局數據。多線程比多進程之間更容易共享數據

1.7.3 虛擬內存

每個進程都有自己的虛擬內存,表現就像是這個進程單獨使用主存一樣。不同的進程看到的虛擬地址空間是一樣的:
在這裏插入圖片描述
虛擬地址空間是從0開始,從最下面的地址一直往上依次增加:
最下面開始依次爲:

  • 程序的代碼和數據,加載程序時完整,是根據可執行目標文件的內容初始化的。
  • 堆,程序開始時,堆就已經初始化了大小,但是它可以根據程序運行時的狀態動態的擴展和收縮(malloc 和 free 函數)
  • 共享庫。 地址的中間會存放代碼的共享庫的代碼和數據。
  • 棧。 用戶虛擬地址空間頂部是棧,是運行時函數調用會用到的內存空間。當調用一個函數,棧就會增長,函數返回時就會收縮。
  • 內核虛擬內存:地址頂層空間的區域是爲內核保留的,不允許用戶直接訪問和讀寫這個區域,必須調用內核來執行該區域的操作。

1.7.4 文件

文件就是字節序列而已,所有的I/O設備都可以抽象的看作爲文件,系統中可能有各式各樣的文件,程序員可以在不懂磁盤讀寫技術的情況下來使用它們

1.8 系統之間利用網絡通信

計算機練上網絡後,就相當於I/O多了一個設備,可以從該設備上獲取數據,也可以往該設備上傳輸數據。就好像是本地計算機的一部分了。
在這裏插入圖片描述

1.9 重要主題

1.9.1 Amdahl定律

本節主要介紹了一個定律Amdahl定律,根據這個定律,我們可以得到一些普遍的指導性的結論: 這定律的主要觀點就是,想要顯著加速整個程序,必須全面提升程序中相當大部分的速率。

1.9.2 併發和並行

現階段的處理器會有多核的情況(將多個處理器集成到一個集成電路芯片上),更先進的會有超線程的處理器,超線程的處理器可以在單個週期內決定執行哪一個線程,(比如I7 處理器 每個核可以執行兩個線程,讓處理器可以在單個週期內決定執行哪個線程,這使得4核的處理器,可以並行地執行8個進程)這使得CPU可以更好的利用計算資源。多核處理器可以併發的執行多個任務,而減少不會出現切換進程的情況。
而在更低的層次上,處理器可以同時執行多條指令的屬性稱爲指令級並行。比如有的處理器就能夠達到每個時鐘週期2~4條指令的執行速度。如果處理器可以達到比一個週期一條指令更快的執行速率,就可以稱之爲超標量(superscalar)處理器。
在最低層次上,一條指令可以並行執行的操作,成爲單指令、多數據,即SIMD並行,這些SIMD指令多是爲了提高處理影像 、聲音等資料的處理速度。更可靠的方法是用編譯器支持的特殊向量數據類型來寫程序,比如GCC就支持向量數據類型。

1.9.3 計算機系統中抽象的重要性

之前的抽象介紹基礎上,再加上一個抽象,虛擬機是對計算機的抽象。
在這裏插入圖片描述

1.10 小結

讀起來很多概念很常見,但是在具體的細節和概念,自己理解還是有很多模糊把握不準的地方,畢竟才第一章,也只是概覽了一下,讀完後面的章節纔回頭來看看吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章