多核程式設計的幾個難題及其應對策略(難題一)
多核程式設計中的負載平衡難題
多核程式設計中的鎖競爭難題
openmp並行程式設計(二)
openmp並行程式設計(一)
雙核cpu上的快速排序效率
隨著多核cpu的出世,多核程式設計方面的問題將擺上了程式設計師的日程,有許多老的程式設計師以為早就有多cpu的機器,業界在多cpu機器上的程式設計已經積累了很多經驗,多核cpu上的程式設計應該差不多,只要借鑑以前的多工程式設計、並行程式設計和並行演算法方面的經驗就足夠了。
我想說的是,多核機器和以前的多cpu機器有很大的不同,以前的多cpu機器都是用在特定領域,比如伺服器,或者一些可以進行大型平行計算的領域,這些領域很容易發揮出多cpu的優勢,而現在多核機器則是應用到普通使用者的各個層面,特別是客戶端機器要使用多核cpu,而很多客戶端軟體要想發揮出多核的並行優勢恐怕沒有伺服器和可以進行大型平行計算的特定領域簡單。
這次參加csdn大會時和孟巖先生聊起多核程式設計時,孟巖先生對多核程式設計的前途感覺到很悲觀,和去年見到他時對多核程式設計的前景看法完全發生了改變。想來孟巖先生對多核程式設計方面有了很深刻的理解,由於時間問題,沒能和孟巖先生在這方面深入聊下去。在回來的路上,我重新思考了一下關於多核程式設計方面的困難之處,今天回到家趕緊把它寫了下來,貼出來分享給大家。
難題一:序列化方面的難題
1)加速係數
衡量多處理器系統的效能時,通常要用到的乙個指標叫做加速係數,定義如下:
s(p) = 使用單處理器執行時間(最好的順序演算法)/ 使用具有p個處理器所需執行時間
2)阿姆爾達定律
並行處理時有乙個阿姆爾達定律,用方程式表示如下:
s(p) = p / (1 + (p-1)*f)
其中 s(p)表示加速係數
p表示處理器的個數
f表示序列部分所佔整個程式執行時間的比例
當f = 5%, p = 20時, s(p) = 10.256左右
當f = 5%, p = 100時, s(p) = 16.8左右
也就是說只要有5%的序列部分,當處理器個數從20個增加到100個時,加速係數只能從10.256增加到16.8左右,處理器個數增加了5倍,速度只增加了60%多一點。即使處理器個數增加到無窮多個,加速係數的極限值也只有20。
如果按照阿姆爾達定律的話,可以說多核方面幾乎沒有任何發展前景,即使軟體中只有1%的不可並行化部分,那麼最大加速系統也只能到達100,再多的cpu也無法提公升速度效能。按照這個定律,可以說多核cpu的發展讓摩爾定律延續不了多少年就會到達極限。
3)gustafson定律
gustafson提出了和阿姆爾達定律不同的假設來證明加速係數是可以超越阿姆爾達定律的限制的,gustafson認為軟體中的序列部分是固定的,不會隨規模的增大而增大,並假設並行處理部分的執行時間是固定的(伺服器軟體可能就是這樣)。gustafson定律用公式描述如下:
s(p) = p + (1-p)*fts 其中
fts 表示序列執行所佔的比例
如果序列比例為
5%,處理器個數為
20個,那麼加速係數為20+
(1-20)*5%=19.05
如果序列比例為
5%,處理器個數為
100個,那麼加速係數為
100+
(1-100)*5%=95.05
gustafson定律中的加速係數幾乎跟處理器個數成正比,如果現實情況符合gustafson定律的假設前提的話,那麼軟體的效能將可以隨著處理個數的增加而增加。
4)實際情況中的序列化分析
阿姆爾達定律和gustafson定律的計算結果差距如此之大,那麼現實情況到底是符合那乙個定律呢?我個人認為現實情況中既不會象阿姆爾達定律那麼悲觀,但也不會象gustafson定律那麼樂觀。為什麼這樣說呢?還是進行一下簡單的分析吧。
首先需要確定軟體中到底有那麼內容不能並行化,才能估計出序列部分所佔的比例,20世紀60年代時,bernstein就給出了不能進行平行計算的三個條件:
條件1:c1寫某一儲存單元後,c2讀該單元的資料。稱為「寫後讀」競爭
條件2:c1讀某一儲存單元資料後,c2寫該單元。稱為「讀後寫」競爭
條件1:c1寫某一儲存單元後,c2寫該單元。稱為「寫後寫」競爭
滿足以上三個條件中的任何乙個都不能進行並行執行。不幸的是在實際的軟體中大量存在滿足上述情況的現象,也就是我們常說的共享資料要加鎖保護的問題。
加鎖保護導致的序列化問題如果在任務數量固定的前提下,序列化所佔的比例是隨軟體規模的增大而減小的,但不幸的是它會隨任務數量的增加而增加,也就是說處理器個數越多,鎖競爭導致的序列化將越嚴重,從而使得序列化所佔的比例隨處理器個數的增加而急劇增加。(關於鎖競爭導致的序列化加劇情況我會在另一篇文章中講解)。所以序列化問題是多核程式設計面臨的一大難題。
5)可能的解決措施
對於序列化方面的難題,首先想到的解決措施就是少用鎖,甚至採用無鎖程式設計,不過這對普通程式設計師來說幾乎是難以完成的工作,因為無鎖程式設計方面的演算法太過於複雜,而且使用不當很容易出錯,許多已經發表到專業期刊上的無鎖演算法後來又被證明是錯的,可以想象得到這裡面的難度有多大。
第二個解決方案就是使用原子操作來替代鎖,使用原子操作本質上並沒有解決序列化問題,只不過是讓序列化的速度大大提公升,從而使得序列化所佔執行時間比例大大下降。不過目前晶元廠商提供的原子操作很有限,只能在少數地方起作用,晶元廠商在這方面可能還需要繼續努力,提供更多功能稍微強大一些的原子操作來避免更多的地方的鎖的使用。
第三個解決方案是從設計和演算法層面來縮小序列化所佔的比例。也許需要發現實用的並行方面的設計模式來縮減鎖的使用,目前業界在這方面已經積累了一定的經驗,如任務分解模式,資料分解模式,資料共享模式,相信隨著多核cpu的大規模使用將來會有更多的新的有效的並行設計模式和演算法冒出來。
第四個解決方案是從晶元設計方面來考慮的,由於我對晶元設計方面一無所知,所以這個解決方案也許只是我的一廂情願的猜想。主要的想法是在晶元層面設計一些新的指令,這些指令不象以前單核cpu指令那樣是由單個cpu完成的,而是由多個cpu進行並行處理完成的一些並行指令,這樣程式設計師呼叫這些並行處理指令程式設計就象編寫序列化程式一樣,但又充分利用上了多個cpu的優勢。
作者介紹:周偉明,自由職業,從事軟體行業十年有餘。目前主要關注軟體測試、多核程式設計、軟體設計等基礎方面的內容。寫有《多工下的資料結構與演算法》一書,目前正在寫作《軟體測試實踐》一書,計畫在不久的將來寫一本多核程式設計方面的書籍。
參考資料:《並行程式設計模式》timothy mattson等著 敖富江譯
《平行計算綜論》jack dongarra等編著 莫則堯等譯
《並行程式設計》barry wilkinson等著 陸鑫達等譯
《多核程式設計技術》shameem akhter等著 李寶峰等譯
《並行演算法實踐》 陳國良等編著
多核程式設計的幾個難題及其應對策略(難題一)
多核程式設計的幾個難題及其應對策略 難題一 多核程式設計中的負載平衡難題 多核程式設計中的鎖競爭難題 openmp並行程式設計 二 openmp並行程式設計 一 雙核cpu上的快速排序效率 隨著多核cpu的出世,多核程式設計方面的問題將擺上了程式設計師的日程,有許多老的程式設計師以為早就有多cpu的...
多核程式設計的幾個難題及其應對策略(難題一)
多核程式設計的幾個難題及其應對策略 難題一 多核程式設計中的負載平衡難題 多核程式設計中的鎖競爭難題 openmp並行程式設計 二 openmp並行程式設計 一 雙核cpu上的快速排序效率 隨著多核cpu的出世,多核程式設計方面的問題將擺上了程式設計師的日程,有許多老的程式設計師以為早就有多cpu的...
多核程式設計的幾個難題及其應對策略(難題一)
多核程式設計的幾個難題及其應對策略 難題一 多核程式設計中的負載平衡難題 多核程式設計中的鎖競爭難題 openmp並行程式設計 二 openmp並行程式設計 一 雙核cpu上的快速排序效率 隨著多核cpu的出世,多核程式設計方面的問題將擺上了程式設計師的日程,有許多老的程式設計師以為早就有多cpu的...