術(shù)語(yǔ)
并發(fā)(concurrency):兩個(gè)或兩個(gè)以上的任務(wù)在一段時(shí)間內(nèi)被執(zhí)行。我們不必care這些任務(wù)在某一個(gè)時(shí)間點(diǎn)是否是同時(shí)執(zhí)行距潘,可能同時(shí)執(zhí)行较锡,也可能不是器腋,我們只關(guān)心在一段時(shí)間內(nèi)月杉,哪怕是很短的時(shí)間(一秒或者兩秒)是否執(zhí)行解決了兩個(gè)或兩個(gè)以上任務(wù)。
并行(parallellism):兩個(gè)或兩個(gè)以上的任務(wù)在同一時(shí)刻被同時(shí)執(zhí)行抠艾。
并發(fā)說(shuō)的是邏輯上的概念苛萎,而并行,強(qiáng)調(diào)的是物理運(yùn)行狀態(tài)检号。并發(fā)“包含”并行腌歉。
計(jì)算機(jī)中的并發(fā):計(jì)算機(jī)領(lǐng)域里,并發(fā)不是一個(gè)新事物:很多年前齐苛,一臺(tái)單核計(jì)算機(jī)就能通過(guò)多任務(wù)操作系統(tǒng)的切換功能翘盖,同時(shí)運(yùn)行多個(gè)應(yīng)用程序;高端多處理器服務(wù)器在很早就已經(jīng)實(shí)現(xiàn)了真正的并行計(jì)算凹蜂。那“老東西”上有哪些“新東西”能讓它在計(jì)算機(jī)領(lǐng)域越來(lái)越流行呢馍驯?——真正任務(wù)并行,而非一種錯(cuò)覺玛痊。
圖1.1顯示了一個(gè)計(jì)算機(jī)處理恰好兩個(gè)任務(wù)時(shí)的理想情景汰瘫,每個(gè)任務(wù)被分為10個(gè)相等大小的塊。在一個(gè)雙核機(jī)器(具有兩個(gè)處理核心)上擂煞,每個(gè)任務(wù)可以在各自的處理核心上執(zhí)行混弥。在單核機(jī)器上做任務(wù)切換時(shí),每個(gè)任務(wù)的塊交織進(jìn)行对省。但它們中間有一小段分隔(圖中所示灰色分隔條的厚度大于雙核機(jī)器的分隔條);為了實(shí)現(xiàn)交織進(jìn)行蝗拿,系統(tǒng)每次從一個(gè)任務(wù)切換到另一個(gè)時(shí)都需要切換一次上下文(context switch)晾捏,任務(wù)切換也有時(shí)間開銷。進(jìn)行上下文的切換時(shí)哀托,操作系統(tǒng)必須為當(dāng)前運(yùn)行的任務(wù)保存CPU的狀態(tài)和指令指針惦辛,并計(jì)算出要切換到哪個(gè)任務(wù),并為即將切換到的任務(wù)重新加載處理器狀態(tài)萤捆。然后裙品,CPU可能要將新任務(wù)的指令和數(shù)據(jù)的內(nèi)存載入到緩存中,這會(huì)阻止CPU執(zhí)行任何指令俗或,從而造成的更多的延遲市怎。
圖1.2顯示了四個(gè)任務(wù)在雙核處理器上的任務(wù)切換,仍然是將任務(wù)整齊地劃分為同等大小塊的理想情況辛慰。實(shí)際上区匠,許多因素會(huì)使得分割不均和調(diào)度不規(guī)則。
并發(fā)示例
試想當(dāng)兩個(gè)程序員在兩個(gè)獨(dú)立的辦公室一起做一個(gè)軟件項(xiàng)目帅腌,他們可以安靜地工作驰弄、不互相干擾,并且他們?nèi)耸忠惶讌⒖际謨?cè)速客。但是戚篙,他們溝通起來(lái)就有些困難,比起可以直接互相交談溺职,他們必須使用電話岔擂、電子郵件或到對(duì)方的辦公室進(jìn)行直接交流。并且浪耘,管理兩個(gè)辦公室需要有一定的經(jīng)費(fèi)支出乱灵,還需要購(gòu)買多份參考手冊(cè)。
假設(shè)七冲,讓開發(fā)人員同在一間辦公室辦公痛倚,他們可以自由的對(duì)某個(gè)應(yīng)用程序設(shè)計(jì)進(jìn)行討論,也可以在紙或白板上輕易的繪制圖表澜躺,對(duì)設(shè)計(jì)觀點(diǎn)進(jìn)行輔助性闡釋〔跷龋現(xiàn)在,你只需要管理一個(gè)辦公室苗踪,只要有一套參考資料就夠了颠区。遺憾的是,開發(fā)人員可能難以集中注意力通铲,并且還可能存在資源共享的問(wèn)題(比如毕莱,“參考手冊(cè)哪去了?”)
以上兩種方法,描繪了并發(fā)的兩種基本途徑。每個(gè)開發(fā)人員代表一個(gè)線程朋截,每個(gè)辦公室代表一個(gè)處理器蛹稍。第一種途徑是有多個(gè)單線程的進(jìn)程,這就類似讓每個(gè)開發(fā)人員擁有自己的辦公室部服,而第二種途徑是在單一進(jìn)程里有多個(gè)線程唆姐,如同一個(gè)辦公室里有兩個(gè)開發(fā)人員。讓我們?cè)谝粋€(gè)應(yīng)用程序中簡(jiǎn)單的分析一下這兩種途徑廓八。
并發(fā)方式
- 多進(jìn)程
- 多線程
并發(fā)時(shí)機(jī)
- 分離關(guān)注點(diǎn)
通過(guò)將相關(guān)的代碼與無(wú)關(guān)的代碼分離奉芦,可以使程序更容易理解和測(cè)試,從而減少出錯(cuò)的可能性剧蹂。 - 為了性能兩種方式利用并發(fā)提高性能:第一声功,將一個(gè)單個(gè)任務(wù)分成幾部分,且各自并行運(yùn)行宠叼,從而降低總運(yùn)行時(shí)間先巴。這就是任務(wù)并行(task parallelism)。雖然這聽起來(lái)很直觀冒冬,但它是一個(gè)相當(dāng)復(fù)雜的過(guò)程伸蚯,因?yàn)樵诟鱾€(gè)部分之間可能存在著依賴。區(qū)別可能是在過(guò)程方面——一個(gè)線程執(zhí)行算法的一部分简烤,而另一個(gè)線程執(zhí)行算法的另一個(gè)部分——或是在數(shù)據(jù)方面——每個(gè)線程在不同的數(shù)據(jù)部分上執(zhí)行相同的操作(第二種方式)剂邮。后一種方法被稱為數(shù)據(jù)并行(data parallelism)。
實(shí)現(xiàn)并發(fā)
線程
線程(thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度和分派的最小單位横侦。它被包含在進(jìn)程之中抗斤,是進(jìn)程中的實(shí)際運(yùn)作單位。一個(gè)線程指的是進(jìn)程中一個(gè)單一順序的控制流丈咐,一個(gè)進(jìn)程中可以并行多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù)龙宏。
同一進(jìn)程中的多條線程將共享該進(jìn)程中的全部系統(tǒng)資源棵逊,如虛擬地址空間,文件描述符和信號(hào)處理等等银酗。但同一進(jìn)程中的多個(gè)線程有各自的調(diào)用棧(call stack)辆影,自己的寄存器環(huán)境(register context),自己的線程本地存儲(chǔ)(thread-local storage)黍特。
一個(gè)進(jìn)程可以有很多線程蛙讥,每個(gè)線程并行執(zhí)行不同的任務(wù),每個(gè)進(jìn)程至少有一個(gè)線程灭衷,在程序啟動(dòng)時(shí)由系統(tǒng)創(chuàng)建次慢,此線程被稱為主線程,負(fù)責(zé)程序主流程;在GUI程序中迫像,也叫做UI線程劈愚,負(fù)責(zé)主流程消息循環(huán),界面刷新和重繪動(dòng)作闻妓。
在多核或多CPU菌羽,或支持Hyper-threading的CPU上使用多線程程序設(shè)計(jì)的好處是顯而易見,即提高了程序的執(zhí)行吞吐率由缆。在單CPU單核的計(jì)算機(jī)上注祖,使用多線程技術(shù),也可以把進(jìn)程中負(fù)責(zé)IO處理均唉、人機(jī)交互而常被阻塞的部分與密集計(jì)算的部分分開來(lái)執(zhí)行是晨,編寫專門的workhorse線程執(zhí)行密集計(jì)算,從而提高了程序的執(zhí)行效率浸卦。
OpenMP
OpenMP(Open Multi-Processing)是一套支持跨平臺(tái)共享內(nèi)存方式的多線程并發(fā)的編程API署鸡,使用C,C++和Fortran語(yǔ)言,可以在大多數(shù)的處理器體系和操作系統(tǒng)中運(yùn)行限嫌,包括Solaris, AIX, HP-UX, GNU/Linux, Mac OS X, 和Microsoft Windows靴庆。包括一套編譯器指令、庫(kù)和一些能夠影響運(yùn)行行為的環(huán)境變量怒医。
MPI
消息傳遞界面/接口(Message Passing Interface炉抒,縮寫MPI)是一個(gè)并行計(jì)算的應(yīng)用程序接口(API),常在超級(jí)電腦稚叹、電腦簇等非共享內(nèi)存環(huán)境程序設(shè)計(jì)焰薄。
PPL
PPL(Parallel Patterns Library, 并行模式庫(kù)) 提供命令式編程模型,以促進(jìn)開發(fā)并發(fā)應(yīng)用程序的可擴(kuò)展性和易用性扒袖。 PPL 構(gòu)建在并發(fā)運(yùn)行時(shí)的計(jì)劃和資源管理組件上塞茅。 通過(guò)提供并行作用于數(shù)據(jù)的泛型安全算法和容器,提高應(yīng)用程序代碼與基礎(chǔ)線程機(jī)制之間的抽象級(jí)別季率。 使用 PPL 還可以開發(fā)通過(guò)為共享狀態(tài)提供替代方案實(shí)現(xiàn)縮放的應(yīng)用程序野瘦。
PPL 提供以下功能:
任務(wù)并行︰ 一種機(jī)制,在 threadpool Windows 來(lái)并行執(zhí)行多個(gè)工作項(xiàng) (任務(wù)) 的工作原理
并行算法︰ 在并發(fā)運(yùn)行時(shí)執(zhí)行操作的基礎(chǔ)上從事并行中的數(shù)據(jù)集合的泛型算法
并行容器和對(duì)象︰ 提供對(duì)其元素的安全并發(fā)訪問(wèn)的泛型容器類型
【參考資料】
OpenMP 入門教程
【并行計(jì)算】用MPI進(jìn)行分布式內(nèi)存編程(一)
【下一篇】
[C++并發(fā)編程實(shí)戰(zhàn)]創(chuàng)建多線程