CPU功能:
1.控制器功能
- 取指令
- 分析指令
(指令控制) PC IR - 執(zhí)行指令,發(fā)出各種操作命令
(操作控制)CU 時序電路 - 控制程序的輸入以及結(jié)果的輸出
(時間控制)CU 時序電路 - 總線管理
- 處理異常情況和特殊請求
(處理中斷)中斷系統(tǒng)
2.運(yùn)算器功能
實(shí)現(xiàn)算數(shù)運(yùn)算和邏輯運(yùn)算
(數(shù)據(jù)加工) ALU 寄存器
cpu 組成
ALU 寄存器 中斷系統(tǒng) CU
硬件架構(gòu)發(fā)展史
硬件架構(gòu)發(fā)展史可以從CPU的發(fā)展史來劃分仇箱。
第一階段:CPU頻率低
早期計算機(jī)沒有復(fù)雜的圖形功能醉旦,CPU核心頻率不高,等于內(nèi)存的頻率犁河,因而它們都直接連接在總線Bus上闽铐。I/O設(shè)備速度相比CPU和內(nèi)存慢了很多琳猫,因而通過I/O控制器來協(xié)調(diào)I/O設(shè)備與總線之間的速度侧到,并讓CPU和I/O設(shè)備能夠通信勃教。
第二階段:CPU倍頻
隨著技術(shù)的發(fā)展,CPU頻率有了很大的提升匠抗,加上圖形功能的要求故源,此時CPU頻率是內(nèi)存頻率的倍數(shù),內(nèi)存頻率跟不上而保持與總線頻率一致戈咳,CPU以倍頻方式與總線進(jìn)行通信心软。3D游戲和多媒體的發(fā)展促使了圖形芯片的誕生,而圖形芯片需要CPU和內(nèi)存之間大量交換數(shù)據(jù)著蛙,I/O總線實(shí)在太慢,人們因而設(shè)計了高速的北橋芯片方便高速交換數(shù)據(jù)耳贬。
北橋+南橋硬件架構(gòu)
北橋運(yùn)行速度高踏堡,如果低速設(shè)備也直接連在北橋,無疑會造成非常復(fù)雜的設(shè)計咒劲。因而引入南橋?qū)iT處理低速設(shè)備顷蟆。
第三階段:多核CPU
技術(shù)的發(fā)展帶來了CPU的頻率提升(從幾十kHz到現(xiàn)在的4GHz),但是總歸會遇到增長瓶頸(CPU制造工藝的物理極限)腐魂,而日益增長的計算需求又要求CPU頻率必須更快帐偎,因而人們想到的方法是通過增加CPU數(shù)量來提升速度,也就是多核CPU蛔屹。
理想情況下速度的提高與CPU數(shù)量成正比削樊,但實(shí)際上是不可能的,原因就是程序并不都能分解成若干個完全不相干的子問題。
書中舉了個很直觀的例子:
一個女人可以花10個月生出一個孩子漫贞,但是10個女人并不能在一個月就能生出一個孩子甸箱。
再比如現(xiàn)在的分布式系統(tǒng),機(jī)器越多迅脐,耗費(fèi)在通信上的時間也自然會越多芍殖。
對于操作系統(tǒng)和程序開發(fā)者來說,需要了解硬件的編程接口標(biāo)準(zhǔn)來通信谴蔑,編寫操作系統(tǒng)和驅(qū)動程序豌骏。
操作系統(tǒng)
硬件處理能力是有限的,操作系統(tǒng)需要做的隐锭,就是除了提供抽象接口之外肯适,管理硬件資源。進(jìn)一步說成榜,就是要通過設(shè)計各種方法來發(fā)揮硬件的所有潛能框舔,也就是硬件的三個核心指標(biāo):CPU、內(nèi)存和I/O赎婚。
CPU:多任務(wù)系統(tǒng)
不能讓CPU閑著刘绣,不能讓CPU一次只能運(yùn)行一個程序,為了提升利用效率挣输,目前正在用而比較先進(jìn)的操作系統(tǒng)模式就是多任務(wù)系統(tǒng)纬凤。它實(shí)現(xiàn)了:讓每個應(yīng)用程序都以進(jìn)程的方式運(yùn)行。每個進(jìn)程都有自己獨(dú)立的地址空間撩嚼,使得進(jìn)程之間的地址空間相互隔離CPU由系統(tǒng)根據(jù)進(jìn)程優(yōu)先級的高低統(tǒng)一分配搶占式的CPU分配機(jī)制可以讓系統(tǒng)強(qiáng)制剝奪CPU資源并分配給它認(rèn)為目前最需要的進(jìn)程系統(tǒng)
如果分配給每個進(jìn)程的時間都很短停士,保證了CPU在多個進(jìn)程間快速的切換,就能造成很多進(jìn)程都在同時運(yùn)行的假象完丽。
I/O:硬件抽象
成熟的操作系統(tǒng)保證訪問硬件設(shè)備和訪問普通的文件形式一樣恋技,操作系統(tǒng)開發(fā)者為硬件生產(chǎn)廠商提供了一系列接口和框架,按照這個接口和框架開發(fā)的驅(qū)動程序都可以在該操作系統(tǒng)上使用逻族。這樣程序員可以從硬件細(xì)節(jié)解脫出來蜻底,更多關(guān)注程序本身。繁瑣的硬件細(xì)節(jié)交給操作系統(tǒng)的硬件驅(qū)動程序來完成聘鳞。
內(nèi)存:虛擬地址
多任務(wù)系統(tǒng)保證了CPU的高利用率薄辅,接下來的問題就是如何將計算機(jī)優(yōu)先的物理內(nèi)存分配給多個程序使用。直接按順序分配內(nèi)存的策略雖然簡單抠璃,但是會遇到三個問題:
- 地址空間不隔離如果所有程序直接訪物理地址站楚,很容易造成一個程序改寫其他程序的內(nèi)存數(shù)據(jù)
- 程序運(yùn)行的地址不確定程序每次運(yùn)行都需要內(nèi)存分配區(qū)域,而程序訪問數(shù)據(jù)和指令跳轉(zhuǎn)時的目標(biāo)地址很多都是固定的搏嗡,這樣便涉及了程序的重定位窿春。
- 內(nèi)存使用效率低簡單分配無法保證有效的內(nèi)存管理機(jī)制,空間連續(xù)切換程序會導(dǎo)致大量數(shù)據(jù)的換入換出,效率底下谁尸。
解決方法就是增加中間層舅踪,使用間接的地址訪問方法。
具體來說良蛮,就是在進(jìn)程和物理地址之間添加虛擬地址實(shí)現(xiàn)進(jìn)程間的隔離抽碌,也就是進(jìn)程 -> 虛擬地址(中間層) -> 物理地址,中間通過映射對應(yīng)起來决瞳。通過創(chuàng)建不存在的虛擬空間货徙,每個進(jìn)程都有了自己獨(dú)立的虛擬空間,而且每個進(jìn)程只能訪問自己的地址空間皮胡,從而有效地做到了進(jìn)程的隔離痴颊。
具體的實(shí)現(xiàn)方法包括分段和分頁兩種。分段是解決分配策略的前兩個問題屡贺,分頁則是解決第三個問題蠢棱。
分段Segmentation
基本思路就是程序需要多少內(nèi)存,就設(shè)置多大的虛擬內(nèi)存并映射到某個物理地址空間甩栈,只要程序訪問虛擬空間的地址超出了設(shè)置的內(nèi)存大小泻仙,硬件自動判斷為非法訪問,拒絕請求量没。這樣它實(shí)現(xiàn)了地址隔離玉转,同時程序不需要重定位,不需要關(guān)心物理地址的變化(因?yàn)橹恍枰凑仗摂M空間的內(nèi)存分配來編寫程序)殴蹄。但分段依然沒有解決內(nèi)存使用效率不高的問題究抓。分段對內(nèi)存區(qū)域的映射還是按照程序?yàn)閱挝唬绻麅?nèi)存不足袭灯,依然會以整個程序?yàn)閱挝贿M(jìn)行換入換出刺下,造成大量磁盤訪問操作從而嚴(yán)重影響速度。整個因果關(guān)系流可以表示為:內(nèi)存不足 -> 整個程序換入換出 -> 大量磁盤訪問操作 -> 嚴(yán)重影響速度
而事實(shí)上妓蛮,程序在運(yùn)行時在某個時間段只會頻繁的使用一小部分?jǐn)?shù)據(jù)怠李,很多數(shù)據(jù)在整個時間段都不會用到,因而完全可以用更小粒度的內(nèi)存分割和映射的方法蛤克,充分利用程序的局部性原理,這種方法就是分頁夷蚊。
分頁P(yáng)aging
分頁的基本方法就是把地址空間人為地等分成固定的頁构挤,以頁為單位進(jìn)行數(shù)據(jù)的存取和交換。
通過一個叫MMU(Memory Management Unit)的部件來實(shí)現(xiàn)頁映射惕鼓。映射流可以表示為:CPU --虛擬地址--> MMU --物理地址--> 物理內(nèi)存
線程及線程安全
在多核CPU基礎(chǔ)之上筋现,多線程是實(shí)現(xiàn)軟件并發(fā)執(zhí)行的一個重要方法。
何謂線程
簡單來說,一個進(jìn)程包含多個線程矾飞,每個線程由線程ID一膨、當(dāng)前指令指針(PC)、寄存器集合和堆棧組成洒沦,各個線程之間共享程序的內(nèi)存空間和進(jìn)程級的資源豹绪,同時又互不干擾的并發(fā)執(zhí)行。
多線程的好處有如下:
- 有效利用進(jìn)程操作的等待時間
- 線程明確分工申眼,比如一個負(fù)責(zé)交互瞒津,另一個負(fù)責(zé)計算。保證程序和用戶之間的交互不被中斷(一個線程很容易中斷)
- 程序邏輯本身要求并發(fā)操作
- 單線程無法發(fā)揮計算機(jī)全部的計算能力括尸,多核CPU+多線程勢在必行
- 數(shù)據(jù)高效率共享
對于單處理器+多線程的情況巷蚪,類似CPU多任務(wù)系統(tǒng),輪流執(zhí)行線程造成每個線程都「看起來」在同時執(zhí)行的假象濒翻,專業(yè)名詞叫線程調(diào)度屁柏。在線程調(diào)度中,線程至少有三種狀態(tài):運(yùn)行Running有送、就緒Ready和等待Waiting互相切換淌喻。
線程安全
因?yàn)榫€程共享程序的內(nèi)存空間和進(jìn)程級的資源,因而一個進(jìn)程訪問的數(shù)據(jù)很可能也被其他線程訪問(改變)娶眷,線程安全處理的就是多線程程序并發(fā)時的數(shù)據(jù)一致性似嗤。不可再分的單指令操作稱為原子操作,原子操作執(zhí)行不會被打斷届宠。如果能夠保證原子操作的正確先后烁落,數(shù)據(jù)讀寫就不會出現(xiàn)問題,但這僅僅適用于比較簡單的場合豌注,復(fù)雜情況下更好的方法是鎖伤塌。
同步與鎖:多線程同時讀寫一個數(shù)據(jù)的安全防護(hù)
為了避免多線程同時讀寫一個數(shù)據(jù)產(chǎn)生不可預(yù)料的后果,需要對多個線程訪問同一個數(shù)據(jù)做同步轧铁。
所謂同步每聪,就是一個線程還沒訪問完一個數(shù)據(jù),其他線程不能再對該數(shù)據(jù)進(jìn)行訪問齿风,從本質(zhì)上講药薯,保證了對數(shù)據(jù)的訪問是原子化了。
同步的最常見方法是鎖救斑。線程訪問數(shù)據(jù)的整個過程是:訪問前獲取鎖 --> 訪問結(jié)束釋放鎖
最簡單的情況自然是二元鎖童本,也稱為二元信號量(Binary Semaphore),只有兩種狀態(tài):占用和非占用脸候。占用時其他線程無法獲取鎖穷娱,直到被釋放轉(zhuǎn)為非占用绑蔫。非占用時第一個線程自然可以獲取鎖。
如果資源能夠允許多個線程并發(fā)訪問泵额,那就是多元信號量配深。顯然二元信號量是特殊情況。一個初始值為N的信號量允許N個線程并發(fā)訪問嫁盲,當(dāng)線程訪問資源時首先獲取信號量篓叶,進(jìn)行如下操作:
semaphore = semaphore - 1;if(semaphore < 0) current thread waiting;else { visit source, then release semaphore semaphore = semaphore + 1; if(semaphore < 1) woke up a waiting thread}
另外幾種同步的方法包括:互斥量Mutex、臨界區(qū)Critical Section亡资、讀寫鎖Read-Write Lock和條件變量Condition Variable澜共。
互斥量與二元信號量類似,不同的地方在于:信號量可以被任意線程獲取并釋放锥腻,而互斥量要求哪個線程獲得嗦董,它就必須要負(fù)責(zé)釋放這個鎖。