計(jì)算機(jī)系統(tǒng)之系統(tǒng)漫游

信息的表示

信息就是位+上下文,系統(tǒng)中的所有信息,包括磁盤文件,程序,存儲(chǔ)器中數(shù)據(jù)以及網(wǎng)路傳輸?shù)臄?shù)據(jù),都是一串位表示的.區(qū)分不同數(shù)據(jù)對(duì)象的唯一方法就是判斷其上下文.
比如11011101這串二進(jìn)制,可以表示221,在java的class文件里可能就代表一個(gè)JVM指令.

程序的編譯

一個(gè)簡(jiǎn)單的C語(yǔ)言程序來(lái)說(shuō),一般要經(jīng)過(guò)預(yù)處理器、編譯器、匯編器和鏈接器的處理,才能被翻譯成一段可執(zhí)行的二進(jìn)制文件。例如一段c語(yǔ)言helloworld程序.

1

程序的運(yùn)行

hello.c已經(jīng)被編譯成可執(zhí)行文件hello.如果在Unix系統(tǒng)中運(yùn)行,需要一個(gè)叫sheel(外殼)的命令行解釋器加載運(yùn)行.

 unix> ./hello
 hello, world
 unix>
  • 系統(tǒng)硬件

我們首先需要了解系統(tǒng)的硬件.

2

總線:貫穿整個(gè)系統(tǒng)的是一組電子管道,也就是總線??偩€傳送的是字,字中的字節(jié)數(shù)字長(zhǎng)與系統(tǒng)相關(guān),比如在32位操作系統(tǒng)當(dāng)中,一個(gè)字是4個(gè)字節(jié),而在64位則是8個(gè)字節(jié)。
I/O設(shè)備:I/O設(shè)備是系統(tǒng)與外部聯(lián)系的通道.I/O設(shè)備(鍵盤、鼠標(biāo)、顯示器等)由控制器(USB控制器)或者適配器(圖形適配器)與I/O總線相連,兩者的區(qū)別在于一個(gè)是主板上的芯片組,一個(gè)是主板插槽上的卡。
主存:它是計(jì)算機(jī)中的一個(gè)臨時(shí)存儲(chǔ)設(shè)備,在處理器執(zhí)行程序的時(shí)候,主存就是臨時(shí)存放數(shù)據(jù)的地方。物理上來(lái)說(shuō),它是由動(dòng)態(tài)隨即存取存儲(chǔ)器芯片DRAM組成,邏輯上來(lái)說(shuō),它是一組連續(xù)的字節(jié)數(shù)組,每一個(gè)字節(jié)都有唯一的地址,地址從0開(kāi)始。
處理器:中央處理單元,是解釋存儲(chǔ)在主存中指令的引擎.處理器的核心是一個(gè)程序計(jì)數(shù)器(PC),它在整個(gè)計(jì)算機(jī)運(yùn)行的期間都會(huì)指向一個(gè)主存中的一個(gè)內(nèi)存地址,而地址當(dāng)中則是一個(gè)計(jì)算機(jī)指令。處理器所做的,就是不停的執(zhí)行程序計(jì)數(shù)器所指向的每一條指令。處理器所做的操作是圍繞主存、寄存器文件以及算術(shù)/邏輯單元(ALU)進(jìn)行的,這里面處理器做的最多的動(dòng)作就是加載(從主存將數(shù)據(jù)復(fù)制到寄存器)、存儲(chǔ)(從寄存器將數(shù)據(jù)復(fù)制到主存)、操作(將兩個(gè)寄存器的內(nèi)容復(fù)制到算術(shù)/邏輯單元進(jìn)行操作,結(jié)果會(huì)再次復(fù)制到寄存器)以及跳轉(zhuǎn)(改變程序計(jì)數(shù)器當(dāng)中的內(nèi)容)。
處理器當(dāng)中提到的是指令集結(jié)構(gòu),不過(guò)實(shí)際當(dāng)中指令集的實(shí)現(xiàn)是非常復(fù)雜的,這么做的目的是為了加速CPU的運(yùn)算速度。我們可以這樣去區(qū)分指令集機(jī)構(gòu)以及微體系結(jié)構(gòu),指令集結(jié)構(gòu)是指令集的抽象描述,而微體系結(jié)構(gòu)則是這個(gè)抽象描述的某一個(gè)具體實(shí)現(xiàn),類似于JAVA虛擬機(jī)與JAVA虛擬機(jī)實(shí)現(xiàn)的關(guān)系。

  • 運(yùn)行過(guò)程

掃描:當(dāng)我們?cè)阪I盤輸入./hello時(shí),linux的外殼程序(也就是命令行)會(huì)掃描我們輸入的字符,將這些字符讀入到寄存器當(dāng)中,然后再放入主存。換句話說(shuō),./hello這幾個(gè)字符是經(jīng)過(guò)了CPU中的寄存器從而到達(dá)了主存。

3

加載:好了外殼程序知道我們要執(zhí)行hello這個(gè)程序了,開(kāi)始加載,此過(guò)程會(huì)利用一種叫做存儲(chǔ)器存取的技術(shù),使得數(shù)據(jù)不通過(guò)寄存器直接到達(dá)主存
4

運(yùn)行并輸出:代碼以及程序所需要的數(shù)據(jù)加載到主存后,CPU就開(kāi)始從main函數(shù)的起始位置,依次執(zhí)行程序中的機(jī)器語(yǔ)言指令。這些指令將"hello,world"這個(gè)字符串依次加載到寄存器,然后傳輸?shù)斤@示器終端顯示.
5

高速緩存

系統(tǒng)在數(shù)據(jù)的傳輸上花費(fèi)了大量的時(shí)間。硬件開(kāi)發(fā)商為了減少這種數(shù)據(jù)傳輸?shù)臅r(shí)間成本,采用一種高速緩存的技術(shù)去減少這種時(shí)間成本.

6

位于處理器芯片上的L1高速緩存速度和寄存器幾乎一樣,容量更大的L2告訴緩存則通過(guò)一條特殊總線連接到處理器,速度慢一些,但仍比主存快.它們采用靜態(tài)隨機(jī)訪問(wèn)存儲(chǔ)器(SRAM)實(shí)現(xiàn),有些系統(tǒng)甚至有L3告訴緩存.

設(shè)備層次

7

每一層上的存儲(chǔ)器都可以作為低一層存儲(chǔ)器的高速緩存.

進(jìn)程與線程

進(jìn)程是操作系統(tǒng)對(duì)一個(gè)正在運(yùn)行的程序的抽象。并發(fā)運(yùn)行,指的是進(jìn)程交錯(cuò)執(zhí)行.操作系統(tǒng)會(huì)記錄每一個(gè)進(jìn)程的狀態(tài),這些狀態(tài)就稱作進(jìn)程的上下文。這些狀態(tài)主要包括了PC,寄存器以及主存的當(dāng)前內(nèi)容。當(dāng)操作系統(tǒng)在進(jìn)程間切換的時(shí)候,也會(huì)切換相應(yīng)的上下文,從而保證進(jìn)程恢復(fù)到之前的狀態(tài).

8

現(xiàn)代系統(tǒng)中,一個(gè)進(jìn)程可以由多個(gè)稱為線程的執(zhí)行單元組成,線程運(yùn)行在進(jìn)程的上下文,共享相同的代碼和數(shù)據(jù).由于共享數(shù)據(jù)更容易,所以線程更高效.

虛擬存儲(chǔ)器

虛擬存儲(chǔ)器是一種抽象概念,為每個(gè)進(jìn)程提供了一個(gè)假象,即每個(gè)進(jìn)程看到的都是一致的存儲(chǔ)器.從物理上講,它包含了I/O設(shè)備以及主存。在邏輯上講,虛擬存儲(chǔ)器被描述為虛擬地址空間.

9

這里的地址自下向上依次增大,可以看出,圖中標(biāo)注了起始地址,分別為0x08048000(32位)以及0x00400000(64位),然后向上分別是只讀代碼和數(shù)據(jù)、讀寫數(shù)據(jù)、運(yùn)行時(shí)堆、共享庫(kù)的內(nèi)存映射區(qū)間、用戶棧以及內(nèi)核虛擬內(nèi)存區(qū)域.
程序代碼和數(shù)據(jù):這些內(nèi)容的起始地址就是0x08048000,首先是代碼,然后是一些全局變量。
:是運(yùn)行時(shí)可以動(dòng)態(tài)擴(kuò)展的一部分內(nèi)存區(qū)域,它可以由malloc和free這樣的標(biāo)準(zhǔn)庫(kù)函數(shù)操作。
共享庫(kù):用于存放共享庫(kù)的代碼和數(shù)據(jù)。
:在用戶虛擬地址空間的頂部是棧,這部分區(qū)域與函數(shù)的執(zhí)行有密切的關(guān)系。
內(nèi)核虛擬存儲(chǔ)區(qū)域:內(nèi)核是操作系統(tǒng)的一部分,內(nèi)核也可以看做是一個(gè)進(jìn)程,它在計(jì)算機(jī)運(yùn)行期間總是在運(yùn)行著,因此這部分內(nèi)存區(qū)域?qū)τ脩舫绦蚴遣豢梢?jiàn)的,通俗的說(shuō)就是不能用。

文件

文件是I/O設(shè)備邏輯上的概念,它其實(shí)就是字節(jié)序列,也就是1和0組成的一些信息。因此所有的I/O設(shè)備,包括磁盤、鍵盤、鼠標(biāo)、顯示器都可以看成是文件.系統(tǒng)中所有輸入輸出都是通過(guò)Unix I/O的系統(tǒng)函數(shù)調(diào)用讀寫文件實(shí)現(xiàn).

網(wǎng)絡(luò)

所有的I/O設(shè)備其實(shí)都是文件這一抽象概念的具體表現(xiàn),那么網(wǎng)絡(luò)其實(shí)也是文件的一種,因?yàn)檎f(shuō)到底,它也可以被看做是一系列的字節(jié)序列。網(wǎng)絡(luò)適配器的作用就是給計(jì)算機(jī)輸入一堆被傳送過(guò)來(lái)的字節(jié)序列,這里面可能包括圖片、文字,甚至可能是代碼等等.

并發(fā)與并行

書中的解釋是并發(fā)是指一個(gè)同時(shí)具有多個(gè)活動(dòng)的系統(tǒng),而并行則是指的用并發(fā)使得一個(gè)系統(tǒng)運(yùn)行的更快.實(shí)際上通俗來(lái)講,在單cpu,并發(fā)是一種切換來(lái)切換去執(zhí)行任務(wù)過(guò)程,而如果有多cpu,并行是真正可以同時(shí)執(zhí)行不同任務(wù)的.
我們按照系統(tǒng)層次結(jié)構(gòu)由高到低強(qiáng)調(diào)三個(gè)層次.

  1. 線程級(jí)并發(fā):
    在進(jìn)程的抽象概念下引入了線程,而線程級(jí)并發(fā)的概念,就是指的多個(gè)線程在同一時(shí)間(并非是絕對(duì)同時(shí)的)活動(dòng)
    操作系統(tǒng)從單處理器,直到現(xiàn)在多核多處理器系統(tǒng),乃至超線程技術(shù),已經(jīng)經(jīng)歷了很大的變化。這也使得針對(duì)多線程編程變得更加重要,否則就無(wú)法利用多處理器帶來(lái)的好處。
    針對(duì)多處理器系統(tǒng)來(lái)說(shuō),比較好理解,其實(shí)就是物理上將多個(gè)CPU集中在一個(gè)集成電路的芯片上。而對(duì)于超線程技術(shù)來(lái)說(shuō),則是利用N個(gè)物理內(nèi)核,模擬出2N個(gè)邏輯內(nèi)核的技術(shù)。在硬件上來(lái)講,超線程需要CPU的某些部分有多個(gè)備份,比如寄存器和程序計(jì)數(shù)器,但是其它部分只有一份,比如ALU.
  2. 指令級(jí)并發(fā)
    指令級(jí)并行的解釋是,如果處理器可以同時(shí)執(zhí)行多條指令,則稱這種屬性為指令級(jí)并行。其實(shí)指令級(jí)并行就是利用了指令的執(zhí)行過(guò)程中會(huì)有不同的階段,或者更精確的說(shuō),是在同一時(shí)間只會(huì)利用部分CPU的硬件,因此可以利用這一點(diǎn)做到多個(gè)指令并行執(zhí)行。
    更好的情況下,現(xiàn)代的很多處理器能夠做到執(zhí)行一條指令的平均時(shí)間尚且不到一個(gè)周期,這種處理器就稱為超標(biāo)量處理器。
  3. 單指令,多數(shù)據(jù)并行
    單指令、多數(shù)據(jù)的概念是指一條指令可以產(chǎn)生多個(gè)并行執(zhí)行的操作的方式。當(dāng)今的一些處理器中配備了特殊的硬件,可以達(dá)到這個(gè)效果。由于產(chǎn)生了多個(gè)并行執(zhí)行的操作,因此就會(huì)涉及到多個(gè)數(shù)據(jù),通俗的講也可以理解為,一條指令操作多個(gè)數(shù)據(jù)。比如書中所提到的例子,一些處理器具有并行地對(duì)4對(duì)單精度浮點(diǎn)數(shù)做加法的指令.

層次結(jié)構(gòu)從高到低,從并發(fā)到并行,區(qū)別應(yīng)該很明顯了.

抽象

抽象的重要性就不需要再?gòu)?qiáng)調(diào)了,它在計(jì)算機(jī)科學(xué)領(lǐng)域有著不言而喻的地位。抽象可以使得一些具體的實(shí)現(xiàn)變的更加易于描述,而且也可以針對(duì)一些實(shí)現(xiàn)的方式作出規(guī)定.
計(jì)算機(jī)系統(tǒng)提供的一些抽象.

10

思考幾個(gè)問(wèn)題

先上一幅圖再說(shuō),假設(shè)我們要對(duì)一些數(shù)字做相加運(yùn)算,顯然我們需要一個(gè)加法器,圖中選取了全加器:

11

這幅圖和前面書上的圖類似,但是多添加了幾點(diǎn),需要考慮的地方
加電自檢:首先操作系統(tǒng)是怎么運(yùn)行起來(lái)的,通電時(shí)首先進(jìn)行自檢,通過(guò)post程序檢查有沒(méi)有哪里壞了,完了芯片bios上的rom寫入到內(nèi)存的特定區(qū)域,完了再另外一個(gè)單獨(dú)區(qū)域(Kernal Space)加載內(nèi)核系統(tǒng),才能開(kāi)始運(yùn)作.
中斷:我們想要通過(guò)鍵盤輸入,那么系統(tǒng)怎么知道我們敲的是鍵盤呢?難道每時(shí)每刻保持監(jiān)視鍵盤么?其實(shí)是我們敲鍵盤時(shí)候會(huì)給出一個(gè)中斷,信號(hào)到南橋后,內(nèi)部會(huì)集成一個(gè)可編程中斷控制器,得知做出行為的是鍵盤.然后再到北橋,控制器等等...
二進(jìn)制?:為什么計(jì)算機(jī)要用二進(jìn)制?假設(shè)我們用八進(jìn)制,那么我們也許需要八根線.因?yàn)樵骷峭ㄟ^(guò)電壓來(lái)標(biāo)識(shí)自身,那么可以設(shè)計(jì)類似1v,2v,..8v分別代表八進(jìn)制的1,2..8.但是如果是小數(shù)怎么辦?一個(gè)高精度小數(shù),用電壓來(lái)標(biāo)識(shí)十分困難.而二進(jìn)制異常簡(jiǎn)單,有電和沒(méi)電就能標(biāo)識(shí)1和0.
加法器:圖上我們畫的是全加器,它會(huì)由兩個(gè)輸入數(shù)字,一個(gè)輸出和,一個(gè)輸入低位,一個(gè)輸出高位(注意這里的一根線可不代表實(shí)際上的一根線,一個(gè)數(shù)字用二進(jìn)制表示意味著可能會(huì)需要多根線).看上去很不錯(cuò),但是如果我們除了輸入數(shù)字需要線以外,輸入指令也需要線.那怎么樣一根線才能又輸入數(shù)據(jù)又可以輸入指令呢.可以用線路復(fù)用,添加一個(gè)控制位,標(biāo)識(shí)輸入類型.
寄存器:要處理連續(xù)的運(yùn)算,前面得出的結(jié)果要重新作為被加數(shù),而后面的電壓因?yàn)樾聰?shù)字的輸入不斷變化,那么前面的數(shù)存到哪里去?寄存器應(yīng)運(yùn)而生.
緩存:需要了解高度緩存出現(xiàn)的理由,cpu運(yùn)算速度太快,而主存運(yùn)算速度太慢,時(shí)間都被浪費(fèi)了,才需要高速緩存.而之所以高速緩存有存在價(jià)值,在于程序局部性原理.這和伸展樹(shù)是很類似的嘛...
12

多任務(wù):早期的系統(tǒng)是所謂單道批處理系統(tǒng),也就是一次執(zhí)行一個(gè)作業(yè),然后一個(gè)接著一個(gè)直到完成.后來(lái)有了所謂多道批處理,也就是多任務(wù)了.那么考慮一個(gè)問(wèn)題,不同的作業(yè)之間可能需要的內(nèi)存也不一樣,怎么分配呢,分配的話每次訪問(wèn)的地址怎么辦,把前面的內(nèi)存空間地址加進(jìn)來(lái)?我們?cè)趯?duì)cpu進(jìn)行時(shí)間切片的同時(shí)也會(huì)對(duì)內(nèi)存進(jìn)行切片(slice),地址則會(huì)重新編寫各自內(nèi)部的地址,如圖中都是從101開(kāi)始...
虛擬內(nèi)存地址:前面說(shuō)過(guò),虛擬存儲(chǔ)空間為讓每個(gè)進(jìn)程都看到一致的存儲(chǔ)空間.試想一個(gè)問(wèn)題,編程時(shí)候每個(gè)程序需要內(nèi)存空間,但每臺(tái)機(jī)器的各自不同,那怎么統(tǒng)一呢?為每臺(tái)機(jī)器的內(nèi)存容量分別編一個(gè)?這就用到虛擬內(nèi)存地址了,32位的機(jī)器不管實(shí)際內(nèi)存是多少,默認(rèn)就是4g,64位同樣.
系統(tǒng)層次:前面提過(guò)存儲(chǔ)器層次,那么現(xiàn)在會(huì)有系統(tǒng)層次,底部自然是一堆硬件,其次我們需要內(nèi)核(系統(tǒng))對(duì)硬件進(jìn)行管理,完了就是程序,程序可以對(duì)內(nèi)核進(jìn)行直接操作,稱為系統(tǒng)調(diào)用但是這種程序編碼十分復(fù)雜.而庫(kù)則是進(jìn)一層的封裝,所以有更多的程序是調(diào)用庫(kù)進(jìn)行編寫的.另外一個(gè)需要提的是,系統(tǒng)怎么知道用戶對(duì)哪個(gè)程序進(jìn)行了操作?這時(shí)候需要shell這種程序了,shell分為圖形化(GUI)與命令行模式(CLI).
兼容性:顯然對(duì)于兼容的庫(kù)開(kāi)發(fā)的程序在不同平臺(tái)上也能運(yùn)行,只要庫(kù)一樣.而如果程序是直接調(diào)用系統(tǒng)內(nèi)核的,那么在不同系統(tǒng)由于硬件可能不兼容的問(wèn)題,那么也許就沒(méi)法運(yùn)行了.這在另一方面也就是API(Application Programming Interface)和ABI(Application Binary Interface)比較大的區(qū)別,前者是定義了源代碼和庫(kù)之間的接口,后者則是描述了應(yīng)用程序(或者其他類型)和內(nèi)核之間的低級(jí)接口.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容