TASK01

編譯系統(tǒng)的工作流程

image-20211214191226063.png

這個(gè)過程雖然是通過一條命令完成的,然而實(shí)際上編譯系統(tǒng)的處理過程卻是非常復(fù) 雜的,大致可以分為四個(gè)階段膏执,分別為預(yù)處理編譯露久、匯編以及鏈接胧后。

image-20211214191313483.png

  • 預(yù)處理

    預(yù)處理器器會根據(jù)以 # 開頭的代碼,來修改原始程序抱环。例如 hello 程序中引入了頭文 件 stdio.h壳快,預(yù)處理器會讀取該頭文件中的內(nèi)容,將其中的內(nèi)容直接插入到源程序中镇草, 結(jié)果就得到了另外一個(gè) C 程序眶痰。即:hello.c 經(jīng)過預(yù)處理器后得到為文本文件 hello.i。

  • 編譯

    編譯器將 hello.i 文件翻譯成 hello.s 文件梯啤,這一階段包括詞法分析竖伯、語法分析、語義 分析因宇、中間代碼生成以及優(yōu)化等等一系列的中間操作七婴。

  • 匯編

    匯編器根據(jù)指令集將匯編程序 hello.s 翻譯成機(jī)器指令,并且把這一系列的機(jī)器指令 按照固定的規(guī)則進(jìn)行打包察滑,得到可重定位目標(biāo)文件 hello.o 打厘。此時(shí) hello.o 雖然是一 個(gè)二進(jìn)制的文件,但是還不能執(zhí)行贺辰,還要經(jīng)歷最后一個(gè)階段:鏈接户盯。

  • 鏈接

    在 hello 這個(gè)程序中,我們調(diào)用了 printf 函數(shù)饲化,這個(gè)函數(shù)是標(biāo)準(zhǔn) C 庫中的一個(gè)函數(shù)莽鸭, 存儲在名為 printf.o 的文件中。鏈接器 (ld)負(fù)責(zé)把 hello.o 和 printf.o 按照一定規(guī)則 進(jìn)行合并吃靠。正是因?yàn)殒溄悠饕獙?hello.o 和 printf.o 的進(jìn)行調(diào)整硫眨,所以 hello.o 才會被 稱之為可重定位目標(biāo)文件。最終經(jīng)過鏈接階段可以得到可執(zhí)行目標(biāo)文件 hello巢块。

硬件架構(gòu)圖

image-20211214191905902.png

CPU架構(gòu)

中央處理單元(Central Processing Unit , CPU)礁阁,也稱處理器,包含PC ( 程序計(jì)數(shù)器:Program Count )夕冲、寄存器堆(Register file)氮兵、ALU(算數(shù)/邏輯計(jì)算單元:Arithmatic/logic Unit)三個(gè)部分.

內(nèi)存

主存(Main Memory),也稱為內(nèi)存歹鱼、運(yùn)行內(nèi)存泣栈,處理器在執(zhí)行程序時(shí),內(nèi)存主要存放程序指令以及數(shù)據(jù)。從物理上講南片,內(nèi)存是由隨機(jī)動態(tài)存儲器芯片組成掺涛;從邏輯上講,內(nèi)存可以看成一個(gè)從零開始的大數(shù)組疼进,每個(gè)字節(jié)都有相應(yīng)地址.

總線

內(nèi)存和處理器之間通過總線來進(jìn)行數(shù)據(jù)傳遞薪缆。實(shí)際上,總線貫穿了整個(gè)計(jì)算機(jī)系統(tǒng)伞广,它負(fù)責(zé)將信息從一個(gè)部件傳遞到另外一個(gè)部件拣帽。通常總線被設(shè)計(jì)成傳送固定長度的字節(jié)塊嚼锄,也就是字(word)减拭,至于這個(gè)字到底是多少個(gè)字節(jié),各個(gè)系統(tǒng)中是不一樣的区丑,32 位的機(jī)器拧粪,一個(gè)字長是4 個(gè)字節(jié);而64 位的機(jī)器沧侥,一個(gè)字長是8 個(gè)字節(jié).

輸入輸出設(shè)備

  • 輸入輸出設(shè)備

    除了處理器可霎,內(nèi)存以及總線,計(jì)算機(jī)系統(tǒng)還包含了各種輸入輸出設(shè)備宴杀,例如鍵盤癣朗、鼠標(biāo)、顯示器以及磁盤等等婴氮。每一個(gè)輸入輸出設(shè)備都通過一個(gè)控制器或者適配器與IO 總線相連.

程序執(zhí)行過程

  • hello.c 經(jīng)過編譯系統(tǒng)得到可執(zhí)行目標(biāo)文件hello斯棒,此時(shí)可執(zhí)行目標(biāo)文件hello 已經(jīng)存放在系統(tǒng)的磁盤上盾致,那么主经,如何運(yùn)行這個(gè)可執(zhí)行文件呢?

  • 在linux 系統(tǒng)上運(yùn)行可執(zhí)行程序:打開一個(gè)shell 程序庭惜,然后在shell 中輸入相應(yīng)可執(zhí)行程序的文件名:linux>./hello

    (shell 是一個(gè)命令解釋程序罩驻,如果命令行的第一個(gè)單詞不是內(nèi)置的shell 命令,shell就會對這個(gè)文件進(jìn)行加載并運(yùn)行. 此處护赊,shell 加載并且運(yùn)行hello 程序惠遏,屏幕上顯示hello,world 內(nèi)容,hello 程序運(yùn)行結(jié)束并退出骏啰,shell 繼續(xù)等待下一個(gè)命令的輸入.)

程序執(zhí)行流程

  1. 首先我們通過鍵盤輸入”./hello” 的字符串节吮,shell 程序會將輸入的字符逐一讀入寄存器,處理器會把hello這個(gè)字符串放入內(nèi)存中判耕。
  2. 當(dāng)我們完成輸入透绩,按下回車鍵時(shí),shell 程序就知道我們已經(jīng)完成了命令的輸入,然后執(zhí)行一系列的指令來來加載可執(zhí)行文件hello帚豪。
  3. 這些指令將hello 中的數(shù)據(jù)和代碼從磁盤復(fù)制到內(nèi)存碳竟。數(shù)據(jù)就是我們要顯示輸出的”hello , world\n” ,這個(gè)復(fù)制的過程將利用DMA(Direct Memory Access)技術(shù)狸臣,數(shù)據(jù)可以不經(jīng)過處理器莹桅,從磁盤直接到達(dá)內(nèi)存。
  4. 當(dāng)可執(zhí)行文件hello中的代碼和數(shù)據(jù)被加載到內(nèi)存中烛亦,處理器就開始執(zhí)行main函數(shù)中的代碼诈泼,main 函數(shù)非常簡單,只有一個(gè)打印功能煤禽。

Hello 程序執(zhí)行過程

image-20211214200139605.png

image-20211214200150363.png

image-20211214200157398.png

Cache至關(guān)重要

隨著半導(dǎo)體技術(shù)的發(fā)展厂汗,處理器與內(nèi)存之間的差距還在持續(xù)增大,針對處理器和內(nèi) 存之間的差異呜师,系統(tǒng)設(shè)計(jì)人員在寄存器文件和內(nèi)存之間引入了高速緩存(cache)娶桦, 比較新的,處理能力比較強(qiáng)的處理器汁汗,一般有三級高速緩存衷畦,分別為 L1 cache ,L2 cache 以及 L3 cache知牌。


image-20211214200553455.png

操作系統(tǒng)

操作系統(tǒng)作用

  1. 防止硬件被失控的應(yīng)用程序?yàn)E用祈争。
  2. 操作系統(tǒng)提供統(tǒng)一的機(jī)制來控制這些復(fù)雜的底層硬件。


    image-20211214201201428.png

操作系統(tǒng)抽象概念

  • 文件是對IO 設(shè)備的抽象
  • 虛擬內(nèi)存是對內(nèi)存和磁盤IO的抽象
  • 進(jìn)程是對處理器角寸、內(nèi)存以及IO設(shè)備的抽象


    image-20211214201058226.png

進(jìn)程

image-20211214203642876.png

現(xiàn)代操作系統(tǒng)中菩混,一個(gè)進(jìn)程實(shí)際上由多個(gè)線程組成,每個(gè)線程都運(yùn)行在進(jìn)程的上下文中扁藕,共享代碼和數(shù)據(jù)沮峡。由于網(wǎng)絡(luò)服務(wù)器對并行處理的需求,線程成為越來越重要的編程模型亿柑。

虛擬內(nèi)存

操作系統(tǒng)為每個(gè)進(jìn)程提供了一個(gè)假象邢疙,就是每個(gè)進(jìn)程都在獨(dú)自占用整個(gè)內(nèi)存空間, 每個(gè)進(jìn)程看到的內(nèi)存都是一樣的望薄,我們稱之為虛擬地址空間1.

下圖為 Linux 的虛擬地址空間疟游,從下往上看,地址是增大的痕支。最下面是 0 地址颁虐。


image-20211214203832810.png
  • 第一個(gè)區(qū)域是用來存放程序的代碼和數(shù)據(jù)的,這個(gè)區(qū)域的內(nèi)容是從可執(zhí)行目標(biāo)文件中加載而來的卧须,例如我們多次提到的 hello 程序另绩。對所有的進(jìn)程來講瞬痘,代碼都是從固定的地址開始。至于這個(gè)讀寫數(shù)據(jù)區(qū)域放的是什么數(shù)據(jù)呢板熊?例如在 C 語言中框全,全局變量就是存放在這個(gè)區(qū)域.

  • 順著地址增大的方向,繼續(xù)往上看就是堆(heap)干签,學(xué)過 C 語言的同學(xué)應(yīng)該用過malloc 函數(shù)津辩,程序中 malloc 所申請的內(nèi)存空間就在這個(gè)堆中。程序的代碼和數(shù) 據(jù)區(qū)在程序一開始的時(shí)候就被指定了大小容劳,但是堆可以在運(yùn)行時(shí)動態(tài)的擴(kuò)展和 收縮.

  • 接下來喘沿,就是共享庫的存放區(qū)域。這個(gè)區(qū)域主要存放像 C 語言的標(biāo)準(zhǔn)庫和數(shù)學(xué)庫這種共享庫的代碼和數(shù)據(jù)竭贩,例如 hello 程序中的 printf 函數(shù)就是存放在這里.

  • 繼續(xù)往上看蚜印,這個(gè)區(qū)域稱為用戶棧(user stack),我們在寫程序的時(shí)候都使用過函數(shù)調(diào)用留量,實(shí)際上函數(shù)調(diào)用的本質(zhì)就是壓棧窄赋。這句話的意思是:每一次當(dāng)程序進(jìn)行函數(shù)調(diào)用的時(shí)候,棧就會增長楼熄,函數(shù)執(zhí)行完畢返回時(shí)忆绰,棧就會收縮。需要注意的是棧的增長方向是從高地址到低地址.

  • 最后可岂,我們看一下地址空間的最頂部的區(qū)域错敢,這個(gè)區(qū)域是為內(nèi)核保留的區(qū)域,應(yīng)用程序代碼不能讀寫這個(gè)區(qū)域的數(shù)據(jù)缕粹,也不能直接調(diào)用內(nèi)核中定義的函數(shù)稚茅,也就是說,這個(gè)區(qū)域?qū)?yīng)用程序是不可見的.

文件

image-20211214204147180.png

所有的 IO 設(shè)備平斩,包括鍵盤亚享,磁盤,顯示器双戳,甚至網(wǎng)絡(luò)虹蒋,這些都可以看成文件, 系統(tǒng)中所有的輸入和輸出都可以通過讀寫文件來完成飒货。

系統(tǒng)之間利用網(wǎng)絡(luò)通信

image-20211214204336095.png

使用本地計(jì)算機(jī)上的telnet客戶端連接遠(yuǎn)程主機(jī)上的 telnet服務(wù)器

當(dāng)我們在 ssh 的 客戶端中輸入 hello 字符串并且敲下回車之后,客戶端的軟件就會通過網(wǎng)絡(luò)將 字符串發(fā)送到 ssh 服務(wù)端峭竣,ssh 服務(wù)端從網(wǎng)絡(luò)端接收到這個(gè)字符串以后塘辅,會將這 個(gè)字符串傳遞給遠(yuǎn)程主機(jī)上的 shell 程序,然后 shell 負(fù)責(zé) hello 程序的加載皆撩,運(yùn) 行結(jié)果返回給 ssh 的服務(wù)端扣墩,最后 ssh 的服務(wù)端通過網(wǎng)絡(luò)將程序的運(yùn)行結(jié)果發(fā) 送給 ssh 的客戶端哲银,ssh 客戶端在屏幕上顯示運(yùn)行結(jié)果


image-20211214204439554.png

阿姆達(dá)爾定律 (Amdahl’s Law, 1967)

α ∈ [0, 1] 是某任務(wù)無法并行處理部分所占的比例. 假設(shè)該任務(wù)的工作量固定,則對任意 n 個(gè)處理器呻惕,相比于 1 個(gè)處理器荆责,能夠取得的加速比滿足:S(n) < 1 .

古斯塔法森定律 (Gustafson’s Law, 1988)

α ∈ [0, 1] 是某任務(wù)無法并行處理部分所占的比例. 假設(shè)該任務(wù)的工作量可以隨著 處理器個(gè)數(shù)縮放,從而保持處理時(shí)間固定. 則對任意 n 個(gè)處理器亚脆,相比于 1 個(gè)處理 器做院,能夠取得的加速比 S (n) 不存在上界.

孫-倪定律 (Sun-Ni’s Law, 1990)

并發(fā)并行

如何獲得更高的計(jì)算能力呢?可以通過以下三種途徑:

  1. 線程級并發(fā);

  2. 指令級并行;

  3. 單指令多數(shù)據(jù)并行

線程級并發(fā)

  • 首先我們看一個(gè)多核處理器的組織結(jié)構(gòu)濒持,下圖的處理器芯片具有四個(gè) CPU 核 心键耕,由于篇幅限制,另外兩個(gè)用省略號代替了柑营。每個(gè) CPU 核心都有自己的 Ll cache 和 L2 cache 屈雄,四個(gè)CPU核心共享 L3 cache,這 4 個(gè) CPU 核心集成在一 顆芯片上官套。

  • 對于許多高性能的服務(wù)器芯片酒奶,單顆芯片集成的 CPU 數(shù)量高達(dá)幾十個(gè),甚至上百個(gè)奶赔。通過增加 CPU 的核心數(shù)讥蟆,可以提高系統(tǒng)的性能。


    image-20211214205443764.png

還有一個(gè)技術(shù)就是超線程(hyperthreading)纺阔,也稱同時(shí)多線程瘸彤。如果每 個(gè) CPU 核心可以執(zhí)行兩個(gè)線程,那么四個(gè)核心就可以并行的執(zhí)行 8 個(gè)線程笛钝。在 CPU 內(nèi)部质况,像程序計(jì)數(shù)器和寄存器文件這樣的硬件部件有多個(gè)備份,而像浮點(diǎn) 運(yùn)算部件這個(gè)樣的硬件還是只有一份玻靡,常規(guī)單線程處理器在做線程切換時(shí)结榄,大概需 要 20000 個(gè)時(shí)鐘周期,而超線程處理器可以在單周期的基礎(chǔ)上決定執(zhí)行哪一個(gè)線程囤捻, 這樣一來臼朗,CPU 可以更好地利用它的處理資源。當(dāng)一個(gè)線程因?yàn)樽x取數(shù)據(jù)而進(jìn)入等 待狀態(tài)時(shí)蝎土,CPU 可以去執(zhí)行另外一個(gè)線程视哑,其中線程之間的切換只需要極少的時(shí)間代價(jià)。

指令級并行

現(xiàn)代處理器可以同時(shí)執(zhí)行多條指令的屬性稱為指佘級并行誊涯,每條指令從開始到結(jié)束大概需要 20 個(gè)時(shí)鐘周期或者更多挡毅,但是處理器采用了非常多的技巧可以同時(shí)處理多達(dá) 100 條指命,因此暴构,近幾年的處理器可以保持每個(gè)周期24條指令的執(zhí)行速率跪呈。


image-20211214210149840.png

單指令多數(shù)據(jù)并行

現(xiàn)代處理器擁有特殊的硬件部件段磨,允許一條指令產(chǎn)生多個(gè)并行的操作,這種方式稱為單指令多數(shù)據(jù)(Single Instruction Multiple Data)耗绿。SIMD 的指令多是為了提高處 理視頻苹支、以及聲音這類數(shù)據(jù)的執(zhí)行速度,比較新的 Intel 以及 AMD 的處理器都是支持 SIMD 指令加速误阻。


image-20211214210234053.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末债蜜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子堕绩,更是在濱河造成了極大的恐慌策幼,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奴紧,死亡現(xiàn)場離奇詭異特姐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)黍氮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門唐含,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沫浆,你說我怎么就攤上這事捷枯。” “怎么了专执?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵淮捆,是天一觀的道長。 經(jīng)常有香客問我本股,道長攀痊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任拄显,我火速辦了婚禮苟径,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘躬审。我一直安慰自己棘街,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布承边。 她就那樣靜靜地躺著遭殉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪炒刁。 梳的紋絲不亂的頭發(fā)上恩沽,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機(jī)與錄音翔始,去河邊找鬼罗心。 笑死,一個(gè)胖子當(dāng)著我的面吹牛城瞎,可吹牛的內(nèi)容都是我干的渤闷。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼脖镀,長吁一口氣:“原來是場噩夢啊……” “哼飒箭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蜒灰,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤弦蹂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后强窖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凸椿,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年翅溺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脑漫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咙崎,死狀恐怖优幸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情褪猛,我是刑警寧澤网杆,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站伊滋,受9級特大地震影響碳却,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜新啼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一追城、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧燥撞,春花似錦座柱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冠胯,卻和暖如春火诸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荠察。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工置蜀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奈搜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓盯荤,卻偏偏與公主長得像馋吗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子秋秤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容