有關爲何要使用並行程序的問題前面已經進行了簡單的探討。總的來講,最重要的應該是處於兩個目的。java
第一,爲了得到更好的性能;算法
第二,因爲業務模型的須要,確實須要多個執行實體。併發
在這裏,我將更加關注第一種狀況,也就是有關性能的問題。將串行程序改造爲併發程序,通常來講能夠提升程序的總體性能,可是究竟能提升多少,甚至說到底是否真的能夠提升,仍是一個須要研究的問題。目前,主要有兩個定律對這個問題進行解答,一個是Amdahl定律,另一個是Gustafson定律。高併發
Amdahl定律是計算機科學中很是重要的定律。它定義了串行系統並行化後的加速比的計算公式和理論上線。性能
加速比定義:加速比 = 優化前系統耗時 / 優化後系統耗時優化
所謂加速比就是優化前耗時與優化後耗時的比值。加速比越高,代表優化效果越明顯。圖1.8顯示了Amdahl公式的推到過程,其中n表示處理器個數,T表示時間,T1表示優化前耗時(也就是隻有1個處理器時的耗時),Tn表示使用n個處理器優化後的耗時。F是程序中只能串行執行的比例。線程
根據這個公式,若是CPU處理器數量趨於無窮,那麼加速比與系統的串行化比例成反比,若是系統中必須有50%的代碼串行執行,那麼系統的最大加速比爲2。3d
假設有一個程序分爲如下步驟執行,每一個執行步驟花費100個單位時間。其中,只有步驟2和步驟5能夠並行,步驟一、三、4必須串行,如圖1.9所示。在全串行的狀況下,系統合計耗時爲500個單位時間。blog
若步驟2和步驟5並行化,假設在雙核處理器上,則有如圖1.10所示的處理流程。在這種狀況下,步驟2和步驟5的耗時將爲50個單位時間。故系統總體耗時爲400個單位時間。根據加速比的定義有:基礎
加速比 = 優化前系統耗時 / 優化後系統耗時 = 500/400 = 1.25
因爲5個步驟中,3個步驟必須串行,所以其串行化比例爲3/5=0.6,即 F = 0.6,且雙核處理器的處理器個數N爲2。代入加速比公式得:
加速比 = 1/(0.6+(1-0.6)/2)=1.25
在極端狀況下,假設並行處理器個數爲無窮大,則有如圖1.11所示的處理過程。步驟2和步驟5的處理時間趨於0。即便這樣,系統總體耗時依然大於300個單位時間。使用加速比計算公式,N趨於無窮大,有加速比 = 1/F,且F=0.6,故有加速比=1.67。即加速比的極限爲500/300=1.67。
因而可知,爲了提升系統的速度,僅增長CPU處理的數量並不必定能起到有效的做用。須要從根本上修改程序的串行行爲,提升系統內可並行化的模塊比重,在此基礎上,合理增長並行處理器數量,才能以最小的投入,獲得最大的加速比。
注意:根據Amdahl定律,使用多核CPU對系統進行優化,優化的效果取決於CPU的數量,以及系統中串行化程序的比例。CPU數量越多,串行化比例越低,則優化效果越好。僅提升CPU數量而不下降程序的串行化比例,也沒法提升系統的性能。
阿姆達爾定律圖示
爲了更好地理解阿姆達爾定律,我會嘗試演示這個定定律是如何誕生的。
首先,一個程序能夠被分割爲兩部分,一部分爲不可並行部分B,一部分爲可並行部分1 – B。以下圖:
在頂部被帶有分割線的那條直線表明總時間 T(1)。
下面你能夠看到在並行因子爲2的狀況下的執行時間:
並行因子爲3的狀況:
舉個例子
一個業務會串行調用2個方法,m1,m2,m1耗時100ms,m2耗時400ms,m2內部串行執行了4個無依賴的任務,每一個任務100ms,以下圖:
m2內部的4個任務無依賴的,便可以並行進行處理,4個任務同時並行,當cpu數量大於等於4的時候,可讓4個任務同時進行,此時m2耗時最小,即100ms,cpu爲2個的時候,同時只可以執行2個任務,其餘2個任務處於等待cpu分配時間片狀態,此時m2耗時200ms;當cpu超過4個的時候,或者趨於無限大的時候,m2耗時仍是100ms,此時cpu數量再怎麼增長對性能也沒有提高了,此時須要提高的是任務能夠並行的數量。
從阿姆達爾定律能夠看出,程序的可並行化部分能夠經過使用更多的硬件(更多的線程或CPU)運行更快。對於不可並行化的部分,只能經過優化代碼來達到提速的目的。所以,你能夠經過優化不可並行化部分來提升你的程序的運行速度和並行能力。你能夠對不可並行化在算法上作一點改動,若是有可能,你也能夠把一些移到可並行化放的部分。
Gustafson定律也試圖說明處理器個數、串行化比例和加速比之間的關係,如圖1.12所示,可是Gustafson定律和Amdahl定律的角度不一樣。一樣,加速比都被定義爲優化前的系統耗時除以優化後的系統耗時。
根據Gustafson定律,咱們能夠更容易地發現,若是串行化比例很小,並行化比例很大,那麼加速比就是處理器的個數。只要不斷地累加處理器,就能得到更快的速度。
Amdahl定律和Gustafson定律結論有所不一樣,並非說其中有個是錯誤的,只是兩者從不一樣的角度去看待問題的結果,他們的側重點有所不一樣。
Amdahl強調:當串行換比例必定時,加速比是有上限的,無論你堆疊多少個CPU參與計算,都不能突破這個上限。
Gustafson定律關係的是:若是可被並行化的代碼所佔比例足夠大,那麼加速比就能隨着CPU的數量線性增加。
總的來講,提高性能的方法:想辦法提高系統並行的比例,同時增長CPU數量。
java高併發系列交流羣