姓名:李鴻彬
學號:16040520011
轉(zhuǎn)載自https://www.zhihu.com/question/21823699,有刪節(jié)
【嵌牛導讀】指令級并行和線程級并行是一種隱式并行,而數(shù)據(jù)級并行是一種顯式并行,線程的概念就是程序的執(zhí)行序,每個執(zhí)行序有執(zhí)行上下文需要保存。
【嵌牛鼻子】指令級并行?線程級并行?數(shù)據(jù)級并行?線程
【嵌牛提問】指令級并行,線程級并行,數(shù)據(jù)級并行區(qū)別?線程的概念是什么?
【嵌牛正文】
進程(processes)與線程(thread)
我們先說個例子:小明的一天
上午:洗臉刷牙,吃早飯,聽音樂
下午: 坐公交到公園玩,
晚上:看電視,睡覺
那么對于小明來說,他可以把一天的宏觀可以分為:上午,下午和晚上 三個部分。
同理:
對一個程序來說,它分為若干個進程:
參照的例子:某個交互程序
進程 A? ? ? ? ? ? ? 用來用戶輸入
進程 B,? ? ? ? ? ? ? ? 用來處理數(shù)據(jù)
進程 C.? ? ? ? ? ? ? 用來數(shù)據(jù)輸出
打個比方恰好是這三個進程。
進程是操作系統(tǒng)處理一個程序時的抽象。
注意:以上的宏觀的角度對吧,上午下午晚上,這個還是太粗略了。process A ,B ,C。對程序來說也是太過于粗略了,接下來我們分的再細一點:
如果我們分的再細致一點,小明的上午繼續(xù)劃分一下,分成是實實在在的小事。
小明的上午:
洗臉刷牙,吃早飯,聽音樂
那么對一個程序來說,它的線程就像發(fā)生在小明這些實實在在的小事。
線程(對進程而言)= 實實在在的小事
線程1 = 刷牙洗臉
線程2 = 吃飯
線程3 =聽音樂
線程4 = 坐公交
……
在這個層面上:
一個程序包含著若干個進程,
一個進程包含著若干個線程。即:
程序>進程>線程? ? 這樣的包含關系
理解線程與進程:
每個線程對cpu來說是一個程序的細小部分,就是cpu當前要處理的一件事。
線程是基于進程的抽象,一個進程在系統(tǒng)層面上分析,進程它是由大量的可執(zhí)行的單元組成,叫做線程(threads) .
<img src="https://pic2.zhimg.com/50/f3c94d03306811a718bdc7fc3d885ffd_hd.png" data-rawwidth="708" data-rawheight="304" class="origin_image zh-lightbox-thumb" width="708" data-original="https://pic2.zhimg.com/f3c94d03306811a718bdc7fc3d885ffd_r.png">
上圖我用于編輯文檔的某個程序,打開任務管理器看到了5個進程。實際上,這些進程又是由許許多多的線程組成。(用戶能看得見進程。線程是用戶看不見的,但cpu看得見。)
再附張生動形象的圖:
<img src="https://pic4.zhimg.com/50/e67d9052f5e275074e2f77e7a3a2f40b_hd.png" data-rawwidth="440" data-rawheight="416" class="origin_image zh-lightbox-thumb" width="440" data-original="https://pic4.zhimg.com/e67d9052f5e275074e2f77e7a3a2f40b_r.png">
圖片摘自Wikipedia
因此我們也可以說:進程是線程的在一定時間內(nèi)有序集合。這些線程對于普通的用戶是不可見的,但是是確實存在的。
-----------------------------------分割線-------------------------------------------------------------
并發(fā)(Concurreny)與并行(Parallelism)的基本概念
接著繼續(xù)說并發(fā)與并行,這個問題還是交給小明回答吧。
并發(fā):小明可以一邊玩手機一邊看電視。
但是事實上,他的眼睛在看電視的時候不能看手機,他在看手機沒法盯著屏幕,他的眼睛飛快在兩個屏幕上切換。
這不是真正意義上的同時進行,但又是客觀存在同時進行兩件事,這叫并發(fā)。
并發(fā)= 小明 “一心兩用 ”? (但不是真正同時進行)
并行: 但是小明可以一天坐公交一邊聽音樂。
這兩件事同時進行互不干擾,做到真正意義的同步同時進行,這叫并行。
并行=小明“一心兩用”? ? (真正的同時進行)
理解并發(fā)和并行的概念后面的就好懂了
-----------------------------------分割線---------------------------------------------------------------
線程級并發(fā)(Thread-Lever Concurrency)
在計算機發(fā)展的早期,計算機每次只能運行一個進程,在OS中能擁有資源和獨立運行基本單位。因此用戶想運行下一個進程必須等上一個進程運行完。比如:你想瀏覽這個網(wǎng)頁就必須關閉上個網(wǎng)頁,你想運行這個線程就必須關閉別的。
在1967年迎來的變化,首次在藍色巨人IBM公司開發(fā)的OS /360系統(tǒng) 實現(xiàn)了多線程(Multiprogamming with a Variable Number of Tasks) ,那時候還沒有建立線程(thread)的概念,他們稱之為任務(Tasks)。
并發(fā)與不并發(fā)這有什么不同之處呢?
這是第一次實現(xiàn)了并發(fā)(Concurrency), 這次并發(fā)實現(xiàn)了用戶可以運行不同的任務,比如網(wǎng)絡服務商可以同時給大量用戶提供網(wǎng)頁,用戶也可以使多個任務并發(fā),比如可以一邊上網(wǎng)一邊聽歌。
對于進程級并發(fā):它不需要cpu的硬件支持,如下圖:
操作系統(tǒng)通過上下文切換(process context switch)實現(xiàn)的,必須下圖中的p1和p2的之前的進程切換,左邊是cpu的時間線。對cpu而言,這兩個進程不是同時進行的;對用戶而言,由于切換的速度非常快,所以用戶覺得是“是同時進行的”。
<img src="https://pic4.zhimg.com/50/v2-4a715c09f793d15e19c84762f72530d7_hd.jpg" data-rawwidth="385" data-rawheight="590" class="content_image" width="385">
IBM只是開發(fā)了一個系統(tǒng)就改變這么多嗎?注意我前面用的詞是并發(fā),因為對真正的計算機而言這些任務并不是真正意義上的同步,而是像小明的那個例子。計算機是如何讓用戶感覺任務同時進行的的呢?
操作系統(tǒng)通過高速的切換不同的線程,仿佛你在同時好多任務一樣。
借用一個例子:
就像一個耍雜技的同時把小球扔在空中。
實際上, 玩雜耍的每次手只碰到了一個球,只是看起來就像能同時處理好多球一樣的樣子。這樣的操作系統(tǒng)我們稱之為 單處理系統(tǒng),(A uniprocessor system is defined as a computer system that has a single central processing unit that is used to execute computer tasks)
------------------------------內(nèi)分割線-----------------------------------------------------------------
線程級并行(Thread-Lever Parallelism)
雖然IBM實現(xiàn)了并發(fā),但這對cpu而言并不是真正意義上的同時進行,只是讓它的效率更高而已,因此人們期望能同時處理多個線程,實現(xiàn)線程的并行。自從1980s開始,系統(tǒng)開發(fā)人員也就已經(jīng)發(fā)出了多處理系統(tǒng)Multiprpcessor system,由單一的操作系統(tǒng)核心控制的多進程的系統(tǒng)。cpu的晶體管也遵循摩爾定律高速發(fā)展。
但問題是——依舊不能同時處理多個線程,僅僅提高單核芯片的速度會產(chǎn)生過多熱量且無法帶來相應的性能改善,也永遠不能實現(xiàn)真正意義上的同時處理多任務。
比如2000年,奔騰四,使用了英特爾發(fā)布最新的NetBurst架構(gòu),按預測,奔騰四在該架構(gòu)下,最終可以把主頻提高到10GHz,但是更高的主頻卻帶來了功耗增加,使其性能上反而還不如早些時推出的產(chǎn)品(摘自百度百科)
英特爾和AMD也意識到,當主頻接近4GHz時,速度也會遇到自己的極限:那就是單靠的主頻提升,已經(jīng)無法明顯提升系統(tǒng)整體性能。
因此迫切需要一個能支持同時處理2個線程以上的處理器,來提升CPU的瓶頸。
需求推動了技術(shù),線程級并行應運而生。主要由下面兩種技術(shù)的支撐:
超線程技術(shù)(Hyper-Threading,簡稱HT)--虛擬內(nèi)核
2004年,奔騰4實現(xiàn)了Hyper-Threadin
2004年,奔騰4實現(xiàn)了Hyper-Threading.(單核心雙線程)
超線程技術(shù)實現(xiàn)了單個物理核心同時兩個線程,也就是別人常說的虛擬內(nèi)核數(shù)。比如單物理核心實現(xiàn)的雙線程,它同時可以處理兩個線程,它的物理核心數(shù)其實是是1個,通過Hyperthreading實現(xiàn)的線程級并行( Thread Lever Parallelism)
多核技術(shù)--物理核心
2005年,英特爾宣布他的第一個雙核心 EM64T 處理器,和 Pentium D840(次年發(fā)布,雙核心雙線程,蹩腳雙核)
2006年,Core 2(雙核心雙線程,但不支持HT技術(shù))這大概才算真正意義上單芯片多核心處理器的誕生。(物理雙核)
而后迎來了 Multi-Core Processor 多內(nèi)核處理器時代,而且伴隨著多線程技術(shù)。也就常說的幾核幾線程。核一般指的是物理核心的數(shù)目,線程是計算機能同時進行的線程。
在1960s :通過操作系統(tǒng)已經(jīng)實現(xiàn)了線程級并發(fā)(雖然那個時候還沒建立線程的概念。)
這種方式依賴操作系統(tǒng),頻繁的上下文切換意味損失了cpu的處理效率。
科學需要一代又一代人的努力吧。但直到2000年隨著CPU的技術(shù)突破以后,從1960s到2000s年前后花了50多年的時間,才實現(xiàn)和更高級的線程級并行。
比如擁有Core i7的每個核心有帶著HP技術(shù),可以同時處理2個線程。而i7有4個物理核心,因此能4x2=8線程并行。非常流弊?。?/p>
附上core i7的架構(gòu)示意圖:(圖片摘自網(wǎng)絡)
<img src="https://pic1.zhimg.com/50/2724475ceb9989f9c43814e88b4fe4e8_hd.jpg" data-rawwidth="500" data-rawheight="452" class="origin_image zh-lightbox-thumb" width="500" data-original="https://pic1.zhimg.com/2724475ceb9989f9c43814e88b4fe4e8_r.jpg">
線程級并行的好處:
1.當運行多任務時,它減少了之前的模擬出來的并發(fā),那么用戶進行多任務處理時可以運行更多的程序進行并發(fā)了。
2.它可以使單個程序運行更快。(僅當該程序有大量線程可以并行處理時)
------------------------------------分割線-----------------------------------------------------------------
指令集并行 Instruction-Level Parallelism
指令集的是更低層次的概念。
計算機處理問題是通過指令實現(xiàn)的。在1978年的 Intel 8086 處理器都只能一次只能單指令。 Intel首次在486芯片中開始使用:當指令之間不存在相關時,它們在流水線中是可以重疊起來并行執(zhí)行。 指令集并行基于流水線(pipeline)技術(shù)。
這個只言片語很難解釋清楚,我舉個例子可能會好點。
顧客A(指令1),顧客B(指令2)這A、B兩個顧客準備去洗車。
而洗車的標準流程是: ①檢查工作 ②撤掉腳墊清洗干凈 ③預洗 ④用水槍沖洗車身 ⑤上洗車液 ⑥涂抹。。后面略
洗衣店可以有兩個方案:
方案一:
洗車店讓A先洗完,A走完整個洗車流程。
再讓顧客B去洗,B走完整個流程。? ? ? ? ? ? 這個效率很低吧?。。?!
方案二:
洗車點讓A先進流程①,
等A到了流程②,立馬讓顧客B開始流程①
等A到了流程③,立馬讓顧客B開始流程②
………依次往復? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 這個效率很高吧!??!
方案二有點像什么?像車間的流水線。 指令1和指令2,實際上不同指令,但是正式因為他們可以互不干擾,因此可以這么執(zhí)行。
數(shù)據(jù)級并行 Multiple-Data parallelism
這是最低的層次。
大型機需要進行科學計算,為了更快的處理數(shù)據(jù),它們使用了更多的寄存器,同時可以處理更多的操作數(shù)。
單一指令運行多個操作數(shù)并行計算。
我們考慮下面這個程序:(a+b)*(c+d)
該計算過程被分解為:
1.? e = a +b
2.? f? = c +d
3.? m =? e * f
早期的計算機一次只能處理一條指令,它要先算1,再算2,最后算3。需要三步(花費三個指令)得到答案。
我們觀察:3的結(jié)果依賴于1和2,而1和2都單純的加法操作,所以開始想辦法讓它們同時計算,cpu只要兩步得到答案,1和2一次算出來,進行乘法運算。它運用了SIMD(Single -Instruction ,Multple -Data)單指令多數(shù)據(jù)流技術(shù)。一個指令執(zhí)行了(a,b,c,d) 4個操作數(shù)。SIMD指令集可以提供更快的圖像,聲音,視頻數(shù)據(jù)等運行速度。
評論區(qū)有人認為這個是指令集并行,顯然把這三個步驟看成三個指令了。注意這三個步驟,,經(jīng)過編譯器分析處理成匯編語言,如果支持數(shù)據(jù)并行的話,它可以被整理成我們邏輯分析的那樣,只需一條指令就執(zhí)行出來了。(當然不支持的話只能當成三個指令去執(zhí)行了)