1. 程式人生 > >Mohican_2/4 連結,裝載與庫 學習筆記— 溫故而知新 計算機硬體基本結構

Mohican_2/4 連結,裝載與庫 學習筆記— 溫故而知新 計算機硬體基本結構

第一章 計算機軟硬體基本結構

引言:

本章是對於計算機軟硬體的基本瞭解和回顧,包括大致如下內容:

ü  CPU與外部件的連線

ü  計算機軟硬體層次結構

ü  SMP與多核

ü  作業系統,虛擬空間,物理空間

ü  多訊號 PV原語的理解

ü  對於執行緒和程序的理解,和深入

1.   1 Hello,world引出的幾個問題

1)      程式為什麼要被編譯器編譯了之後才可以執行?

2)      編譯器在把C語言程式轉換成可以執行的機器碼的過程中做了什麼,怎麼做的?

3)      最後編譯出來的可執行檔案裡面是什麼?除了機器碼還有什麼?它們怎麼存放的,怎麼組織的?

4)      #include<stdio.h>是什麼意思?把stdio.h包含進來意味著什麼?C語言庫又是什麼?它怎麼實現的?

5)      不同的編譯器(Microsoft VC, GCC)和不同的硬體平臺(x86, SPARC,MIPS, ARM),以及不同的作業系統(Windows,Linux,   UNIX, Solar), 最終編譯出來的結果一樣嗎?為什麼?

6)      Hello World 程式是怎麼執行起來的? 作業系統是怎麼裝載它的? 它從哪兒開始執行,到哪兒結束?main函式之前發生了什麼? main函式結束以後又發生了什麼?

7)      如果沒有作業系統,Hello World可以執行嗎?如果要在一臺沒有作業系統的機器上執行Hello World需要什麼?應該怎麼實現?

8)      printf是怎麼實現的?它為什麼可以有不定數量的引數?為什麼能夠在終端上輸出字串?

9)      Hello World程式在執行時,它在記憶體中是什麼樣子的?

1.2萬變不離其宗——硬體

1.2.1計算機硬體主要組成:

中央處理器(CPU,CentralProcessing Unit)

記憶體(Memory)

I/O輸入/輸出(Input/Output)

1.2.2南橋北橋晶片(South Bridge/North Bridge)

隨著CPU頻率的提高,記憶體跟不上CPU速度,於是產生了記憶體頻率一致的系統匯流排,為了協調CPU,記憶體,和高速圖形裝置設計了高速的北橋晶片,交換資料。設計了南橋晶片,處理低速裝置。

北橋晶片(South Bridge)

北橋主要控制 CPU記憶體顯示卡等高速裝置。也就是說CPU想和其他任何部分通訊必須經過北橋。北橋晶片中通常整合的還有記憶體控制器等,用來控制與記憶體的通訊。現在的主機板上已經看不到北橋了,它的功能已經被整合到CPU當中了。

南橋晶片(North Bridege)

南橋晶片主要控制I/O輸入輸出流,如USB,PCI匯流排等低速裝置。CPU要想訪問外設必須經過南橋晶片。

FSB匯流排(Front Side Bus):

即前端匯流排,CPU和北橋之間的橋樑,CPU和北橋傳遞的所有資料必須經過FSB匯流排,可以這麼說FSB匯流排的頻率直接影響到CPU訪問記憶體的速度。

PCI匯流排(Peripheral ComponentInterconnect):

PCI匯流排即外設部件互連標準,是一種高效能區域性匯流排,其不受CPU限制,構成了CPU和外設之間的高速通道。比如現在的顯示卡一般都是用的PCI插槽,PCI匯流排傳輸速度快,能夠很好地讓顯示卡和CPU進行資料交換。

2.    SMP與多核

為了提高CPU頻率,於是想從另一個角度提高CPU的速度,便增加CPU的數量

對稱多處理器(SymmetricMulti-Processor)

一個計算機上彙集了一組處理器(多CPU)。

各CPU之間共享記憶體子系統以及匯流排結構。雖然同時使用多個CPU,但是從管理的角度來看,它們的表現就像一臺單機一樣。

多核處理器(Multi-core processor)

   一枚處理器中整合兩個或多個完整的計算引擎(核心),此時處理器能支援系統總線上的多個處理器,由匯流排控制器提供所有匯流排控制訊號和命令訊號。

1.3站得高,望得遠——軟體體系

1.計算機軟體體系結構採用層的結構

介面(Interface)

   每個層次之間互相通訊,必須有一個通訊協議,將其稱為介面。

   介面上層:介面的使用者; 介面下層:介面的提供者

應用程式(Application)

開發工具和應用程式在該層結構中屬於一個層次,因為他們共用一個介面—API

應用程式程式設計介面(Application Programming Interface)

是一些預先定義的函式,目的是提供應用程式與開發人員基於某軟體或硬體得以訪問一組例程的能力,而又無需訪問原始碼,或理解內部工作機制的細節。類似於標頭檔案??

執行庫(Runtime Library)

使用作業系統提供的系統呼叫介面。是一個經過封裝的程式模組,對外提供介面,只要知道介面引數就可以自由使用。我們把常用的功能都封裝在一個個“庫檔案”中(通常以DLL形式提供),只需要在使用時呼叫的就可以。常見的執行庫有 C/C++ 執行庫、VB 執行庫、Delphi 執行庫、.NET執行庫、Java 執行庫等等

系通呼叫介面(System Call Interface)

    執行庫使用作業系統提供的系統呼叫介面,其實現往往以軟中斷的形式

作業系統核心(Operating System)

 核心層對於硬體層來說是硬體介面的使用者,而硬體則是介面的定義者。

作業系統核心是指大多數作業系統的核心部分。它由作業系統中用於管理儲存器、檔案、外設和系統資源的那些部分組成。作業系統核心通常執行程序,並提供程序間的通訊。

硬體規格(Hardware Specification)

      各種硬體介面標準

1.4作業系統做什麼

作業系統位於底層硬體與使用者之間,是兩者溝通的橋樑。使用者可以通過作業系統的使用者介面,輸入命令。作業系統則對命令進行解釋,驅動硬體裝置,實現使用者要求

1.4.1不要讓CPU打盹

多道程式(Multiprigramming)

提高CPU的利用率。在多道程式環境下,多個程式共享計算機資源當某個程式等待I/O操作時,CPU可以執行其他程式,大大提高CPU的利用率。

分時系統(Time-Share System)

一種聯機的多使用者互動式的作業系統。一般採用時間片輪轉的方式使一臺計算機為多個終端服務。對每個使用者能保證足夠快的響應時間,並提供互動會話能力。

多工系統(Multi-Tasking)

     作業系統直接接管了所有硬體資源,所有應用程式以程序的方式執行在在比作業系統許可權更低的級別,並且每個程序擁有自己獨立的地址空間,(相互隔離),CPU由作業系統根據優先順序統一分配。巨集觀上看,這些程式都正在執行;微觀上看,這些程式所對應的諸程序正在交替地執行,因為任何一個時刻只能有一個程序在處理機(CPU)上執行的。

1.4.2    裝置驅動

硬體驅動程式(DeviceDriver)

一種可以使計算機和裝置通訊的特殊程式。相當於硬體的介面,作業系統只有通過這個介面,才能控制硬體裝置的工作,假如某裝置的驅動程式未能正確安裝,便不能正常工作

硬碟:

硬碟—>碟片—>面—>磁軌—>扇區

1.5記憶體不夠怎麼辦

作業系統的多工性使得CPU在多個程序之間共享,從程序的角度來看,就是一個程序獨佔一個CPU,IO抽象模型也很好地實現了IO裝置的共享,那麼記憶體的分配與共享就交給虛擬儲存器來管理了。

早期計算機中,程式是直接執行在實體記憶體上的,就是程式執行時訪問的都是PA(實體地址),我們必須同時在記憶體中執行多個程式,那麼有限的RAM空間如何分配呢?

直接分配的策略有如下問題:

1.地址空間不隔離,所有程式直接訪問PA,記憶體空間沒有隔離,惡意修改資料有可能造成安全問題。

2.記憶體使用率低下,程式之間換進換出(RAM和Disk之間),因為這裡還沒有分段和分頁機制。

3.程式執行的地址不確定。

1.5.1隔離

首先引入虛擬地址的概念,把程式給出的地址看成是VA(虛擬地址),通過對映機制(MMU+paging)把VA翻譯成PA,這樣只需管理這個VA到PA的對映過程就可以保證程式之間的PA區域不會重疊。

每個程序都有自己獨立的VA空間,每個程序只能訪問自己的虛擬地址空間,這樣做到程序隔離。

1.5.2分段(Segmentation)

程式所需要的記憶體空間大小的虛擬空間對映到每個實體地址空間中,一一對映,它能解決隔離問題,不同的實體地址空間,但是分段沒有解決記憶體使用率低下的問題,分段對記憶體區域的對映是按照程式為單位的,如果記憶體不足,被換入換出到磁碟的都是整個程式,造成大量的磁碟訪問,粒度較大。根據程式的區域性性原理,一個程式執行時,在某個時間段內,它只是頻繁使用到了一部分資料和指令,更小粒度的記憶體分割和對映方法---->分頁機制。提高記憶體使用率。

1.5.3分頁(Paging)

  我們可以把程序的虛擬地址空間按頁分割,一般一個page的大小為4KB或者8KB,把常用的資料和程式碼裝載到RAM中,把不常用的程式碼和資料儲存在Disk中,等到需要使用的時候通過page fault調入RAM,這時候如果沒有空閒的頁,那麼會使用頁面替換演算法犧牲一個頁來覆蓋(LRU最近最少使用演算法)。

通過頁對映機制,可以儲存程式資料,我們可以給每個頁設定許可權屬性(一些標誌位)來控制該頁的訪問許可權(核心還是使用者)還有RWX許可權等。分頁需要MMU(MemoryMangement Unit)硬體單元,該單元整合在CPU內部。

1.6執行緒(Thread)

1.6.1執行緒基礎

1.定義:

執行緒(Thread),是CPU資源分配的最小單位,是程式執行流的最小單元。一個標準的執行緒由執行緒ID,當前指令指標(PC),暫存器集合和堆疊組成。

程序(Process), 是CPU資源分配的基本單位。是計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業系統結構的基礎。在當代面向執行緒設計的計算機結構中,程序是執行緒的容器。程式是指令、資料及其組織形式的描述,程序是程式的實體。

執行緒與程序的區別可以歸納為以下4點:

Ø  地址空間和其它資源(如開啟檔案):程序間相互獨立,同一程序的各執行緒間共享。某程序內的執行緒在其它程序不可見。

Ø  通訊:程序間通訊IPC,執行緒間可以直接讀寫程序資料段(如全域性變數)來進行通訊——需要程序同步和互斥手段的輔助,以保證資料的一致性。

Ø  排程和切換:執行緒上下文切換比程序上下文切換要快得多。

Ø  在多執行緒OS中,程序不是一個可執行的實體。

2.    執行緒的訪問許可權

執行緒可以訪問程序記憶體中的所有資料,如果知道其他執行緒的堆疊地址,甚至可以訪問其他執行緒中的資料。

3.    執行緒排程與優先順序

當執行緒數量小於處理器數量的時候,執行緒總是“併發”執行的。當單處理器對應多執行緒的時候,“併發”是一種模擬的狀態。(作業系統會讓這些多執行緒程式輪流執行),這樣每個執行緒看起來就像是同時執行(有點類似於數學中的微元法?)

執行緒排程(ThreadSchedule)

在處理器上切換不同的執行緒的行為。執行緒通常至少包括三種狀態:

Ø  執行(Running):執行緒正在執行;

Ø  就緒(Ready):可以立即執行,但是CPU已經被佔用;

Ø  等待(Waiting):此時執行緒正在等待某一事件(通常是I/O同步)發生,無法執行

BUT,百度百科定義和這個有點差異,在JAVA中,

2. 五種程序排程演算法的總結:

(1)時間片輪轉排程演算法(RR):給每個程序固定的執行時間,根據程序到達的先後順序讓程序在單位時間片內執行,執行完成後便排程下一個程序執行,時間片輪轉排程不考慮程序等待時間和執行時間,屬於搶佔式排程。優點是兼顧長短作業;缺點是平均等待時間較長,上下文切換較費時。適用於分時系統。

(2)先來先服務排程演算法(FCFS):根據程序到達的先後順序執行程序,不考慮等待時間和執行時間,會產生飢餓現象。屬於非搶佔式排程,優點是公平,實現簡單;缺點是不利於短作業。

(3)優先順序排程演算法(HPF):在程序等待佇列中選擇優先順序最高的來執行。

(4)多級反饋佇列排程演算法:將時間片輪轉與優先順序排程相結合,把程序按優先順序分成不同的佇列,先按優先順序排程,優先順序相同的,按時間片輪轉。優點是兼顧長短作業,有較好的響應時間,可行性強,適用於各種作業環境。

(5)高響應比優先排程演算法:根據“響應比=(程序執行時間+程序等待時間)/ 程序執行時間”這個公式得到的響應比來進行排程。高響應比優先演算法在等待時間相同的情況下,作業執行的時間越短,響應比越高,滿足段任務優先,同時響應比會隨著等待時間增加而變大,優先順序會提高,能夠避免飢餓現象。優點是兼顧長短作業,缺點是計算響應比開銷大,適用於批處理系統。

優先順序排程的環境下,現成的優先順序改變一般有三種方式

1.    使用者指定優先順序

2.    根據等待的頻繁程度提高或者降低優先順序

3.    長時間得不到執行從而提升優先順序

4.    根據等待實踐區分的兩種執行緒

IO密集型執行緒(IO Bound Thread)

  頻繁等待 I/O,input 和output,在輸入輸出方面消耗大。IO密集型執行緒是針對於IO操作比CPU計算操作佔用更多的CPU時間來說的。比如:資料庫伺服器,這個伺服器中的執行緒的職責就是進行阻塞的IO操作。當執行緒因為IO阻塞而進入阻塞狀態後,該執行緒的排程被作業系統核心立即停止,不再佔用CPU時間片段,而其他IO執行緒能立即被作業系統核心排程,等IO阻塞操作完成後,原來阻塞狀態的執行緒重新變成就緒狀態,而可以被作業系統排程。所以,像資料庫伺服器中的IO密集型執行緒來說,執行緒的數量就應該適量的多點。

CPU密集型執行緒(CPU Bound Thread)

很少等待,CPU使用頻率高,消耗大。CPU密集型執行緒的作用是進行無阻塞的邏輯運算的執行緒。比如:RPG遊戲中的遊戲邏輯伺服器(也叫地圖伺服器)裡面的主邏輯執行緒,這個主邏輯執行緒需要進行大量的無阻塞的邏輯處理。當被作業系統核心排程的時候,這個執行緒就在給定的CPU執行時間內進行無阻塞的操作。如果這個遊戲邏輯伺服器還建立更多的執行緒來進行邏輯操作的話,這樣的行為是得不嘗失的。因為,本程序的執行緒越多,而本程序獲取的CPU執行時間又是固定的,導致了程序內每個執行緒的執行時間很短。所以,像遊戲邏輯伺服器中的執行緒應該屬於CPU密集型執行緒。所以執行緒不宜過多。

4.可搶佔執行緒與不可搶佔執行緒

  執行緒在用盡時間片後,強制剝奪繼續執行的權利,進入就緒狀態,這個過程叫做搶佔(Preemption)

執行緒的排程有搶佔式或者非搶佔的模式。

詳情:https://www.cnblogs.com/chllovegeyuting/archive/2012/10/13/2722251.html

5.    Linux的多執行緒

Linux核心中並不存在真正意義上的執行緒概念,Linux將所有的提醒實體(無論是執行緒還是程序)都成為任務(Task),每一個任務概念上都類似於一個單執行緒的程序——具有記憶體空間,執行實體,檔案資源等。

在Linux下,用以下方法可以建立一個新的任務。

1.6.2執行緒安全

多執行緒程式,可訪問的全域性變數和堆疊,隨時都可能被其他的執行緒改變,因此,多執行緒程式在併發的時候,一致性非常重要。

1.    競爭與原子操作

原子(Atomic)操作 不會被執行緒排程機制打斷的操作

2.    同步與鎖

同步(Synchronization)

一個執行緒訪問資料未結束時,其他執行緒不得對同一個資料進行訪問。則對資料的訪問便原子化了(不可被打斷)。

鎖(Lock)

同步的最常見的方法。鎖是一種非強制的機制,每一個執行緒在訪問資源之前先獲取(Acquire)鎖,在結束資料訪問之後釋放(Release)鎖。在鎖被佔用的時候,獲取鎖,執行緒會等待,直到鎖被釋放。

執行緒同步的幾種方式:

二元訊號量binary Semaphore

信 號 量

Semaphore

互斥量

Mutex

臨界區   Critical Section

條件變數

Condition

Variable

讀寫鎖   Read-Write Lock

兩種狀態:

佔用/非佔用

適合只能被唯一一個執行緒獨佔訪問的資源,當而源訊號量被佔用時,其訊號量被置為佔用狀態,其他的試圖獲取的執行緒進入等待狀態,直至被釋放

PV原語

P(進入)

訊號量 S – 1

S–1>=0繼續執行

S-1<0,等待排程

V(釋放)

訊號量S +1

S+1>0,繼續執行

S+1<=0,喚醒等待的

僅同時允許一個執行緒訪問,誰獲取互斥量,誰就要釋放這個鎖。

但二元訊號量,在整個系統可以被任意執行緒獲取並釋放。

獲取鎖:進入臨界區

釋放鎖:離開臨界區

作用範圍僅限於本程序,其他程序無法獲取該鎖。

使用條件變數,可以讓許多執行緒一起等待某個時間的發生,當事件發生時候(條件變數被喚醒),所有執行緒可以一起恢復執行

一次只有一個執行緒可以佔有寫模式的讀寫鎖。

當讀寫鎖在讀加鎖狀態時, 所有試圖以讀模式對它進行加鎖的執行緒都可以得到訪問權, 但是如果執行緒希望以寫模式對此鎖進行加鎖, 它必須直到所有的執行緒釋放鎖.

3.    可重入與執行緒安全

可重入(Reentrant) 表示一個函式沒有執行完成。,一個可重入函式在多執行緒環境下可以放心使用。

一個函式要被重入一般有兩種情況:

Ø    多個執行緒同時執行

Ø    函式自身呼叫自身(遞迴)

一般具有以下特點:

(1)    不使用任何(區域性)靜態或全域性的const常量;

(2)    不返回任何(區域性)靜態或全域性的const指標;

(3)    僅依賴於呼叫方提供的函式;

(4)    不以來任何單個資源的鎖(MUTEX等)

(5)    不呼叫任何不可重入的函式

4.過度優化

1.6.3多執行緒內部情況

1.執行緒的實現曾有3種模型:

Ø  多對一(M:1)的使用者級執行緒模型

Ø  一對一(1:1)的核心級執行緒模型

Ø  多對多(M:N)的兩級執行緒模型

上面的x對y(x:y)即x個使用者執行緒對應y個核心排程實體(KernelScheduling Entity,這個是核心分配CPU的物件單位)。

多對一使用者線級程模型                     

多對一執行緒模型中,執行緒的建立、排程、同步的所有細節全部由程序的使用者空間執行緒庫來處理。使用者態執行緒的很多操作對核心來說都是透明的,因為不需要核心來接管,這意味不需要核心態和使用者態頻繁切換。執行緒的建立、排程、同步處理速度非常快。當然執行緒的一些其他操作還是要經過核心,如IO讀寫。這樣導致了一個問題:當多執行緒併發執行時,如果其中一個執行緒執行IO操作時,核心接管這個操作,如果IO阻塞,使用者態的其他執行緒都會被阻塞,因為這些執行緒都對應同一個核心排程實體。在多處理器機器上,核心不知道使用者態有這些執行緒,無法把它們排程到其他處理器,也無法通過優先順序來排程。這對執行緒的使用是沒有意義的!

一對一核心極執行緒模型                     

一對一模型中,每個使用者執行緒都對應各自的核心排程實體。核心會對每個執行緒進行排程,可以排程到其他處理器上面。當然由核心來排程的結果就是:執行緒的每次操作會在使用者態和核心態切換。另外,核心為每個執行緒都對映排程實體,如果系統出現大量執行緒,會對系統性能有影響。但該模型的實用性還是高於多對一的執行緒模型。

多對多兩極執行緒模型                          

多對多模型中,結合了1:1和M:1的優點,避免了它們的缺點。每個執行緒可以擁有多個排程實體,也可以多個執行緒對應一個排程實體。聽起來好像非常完美,但執行緒的排程需要由核心態和使用者態一起來實現。可想而知,多個物件操作一個東西時,肯定要一些其他的同步機制。使用者態和核心態的分工合作導致實現該模型非常複雜。NPTL曾經也想使用該模型,但它太複雜,要對核心進行大範圍改動,所以還是採用了一對一的模型。

拓展知識:

(在學習過程中附加)

IOS七層模型

單片核心

此次學習要求:

1.    瞭解專業名詞,以及其英文全稱

2.    在學習之前簡歷思維導圖,清楚整個層次體系

3.    增加拓展內容

4.    在每一章節之前寫引言,包括本章節牽扯到的知識