阿姆達爾定律

2021-08-27 23:21:53 字數 3495 閱讀 6447

阿姆達爾定律可以用來計算處理器平行運算之後效率提公升的能力。阿姆達爾定律因 gene amdal 在 1967 年提出這個定律而得名。絕大多數使用並行或併發系統的開發者有一種併發或並行可能會帶來提速的感覺,甚至不知道阿姆達爾定律。不管怎樣,了解阿姆達爾定律還是有用的。

我會首先以算術的方式介紹阿姆達爾定律定律,然後再用圖表演示一下。

乙個程式(或者乙個演算法)可以按照是否可以被並行化分為下面兩個部分:

假設乙個程式處理磁碟上的檔案。這個程式的一小部分用來掃瞄路徑和在記憶體中建立檔案目錄。做完這些後,每個檔案交個乙個單獨的執行緒去處理。掃瞄路徑和建立檔案目錄的部分不可以被並行化,不過處理檔案的過程可以。

程式序列(非並行)執行的總時間我們記為 t。時間 t 包括不可以被並行和可以被並行部分的時間。不可以被並行的部分我們記為 b。那麼可以被並行的部分就是 t-b。下面的列表總結了這些定義:

從上面可以得出:

t = b + (t – b)

首先,這個看起來可能有一點奇怪,程式的可並行部分在上面這個公式中並沒有自己的標識。然而,由於這個公式中可並行可以用總時間 t 和 b(不可並行部分)表示出來,這個公式實際上已經從概念上得到了簡化,也即是指以這種方式減少了變數的個數。

t- b 是可並行化的部分,以並行的方式執行可以提高程式的執行速度。可以提速多少取決於有多少執行緒或者多少個 cpu 來執行。執行緒或者 cpu 的個數我們記為 n。可並行化部分被執行的最快時間可以通過下面的公式計算出來:

(t – b ) / n

或者通過這種方式

(1 / n) * (t – b)

維基中使用的是第二種方式。

根據阿姆達爾定律,當乙個程式的可並行部分使用 n 個執行緒或 cpu 執行時,執行的總時間為:

t(n) = b + ( t – b ) / n

t(n)指的是在並行因子為 n 時的總執行時間。因此,t(1)就執行在並行因子為 1 時程式的總執行時間。使用 t(1)代替 t,阿姆達爾定律定律看起來像這樣:

t(n) = b + (t(1) – b) / n

表達的意思都是是一樣的。

為了更好的理解阿姆達爾定律,讓我們來看乙個計算的例子。執行乙個程式的總時間設為 1。程式的不可並行化占 40%,按總時間 1 計算,就是 0.4,可並行部分就是 1–0.4=0.6.

在並行因子為 2 的情況下,程式的執行時間將會是:

t(2) = 0.4 + ( 1 - 0.4 ) / 2

= 0.4 + 0.6 / 2

= 0.4 + 0.3

= 0.7

在並行因子為 5 的情況下,程式的執行時間將會是:

t(5) = 0.4 + ( 1 - 0.4 ) / 5

= 0.4 + 0.6 / 6

= 0.4 + 0.12

= 0.52

阿姆達爾定律圖示

為了更好地理解阿姆達爾定律,我會嘗試演示這個定定律是如何誕生的。

首先,乙個程式可以被分割為兩部分,一部分為不可並行部分 b,一部分為可並行部分 1–b。如下圖:

在頂部被帶有分割線的那條直線代表總時間 t(1)。

並行因子為 3 的情況:

從阿姆達爾定律可以看出,程式的可並行化部分可以通過使用更多的硬體(更多的執行緒或 cpu)執行更快。對於不可並行化的部分,只能通過優化**來達到提速的目的。因此,你可以通過優化不可並行化部分來提高你的程式的執行速度和並行能力。你可以對不可並行化在演算法上做一點改動,如果有可能,你也可以把一些移到可並行化放的部分。

如果你優化乙個程式的序列化部分,你也可以使用阿姆達爾定律來計算程式優化後的執行時間。如果不可並行部分通過乙個因子 o 來優化,那麼阿姆達爾定律看起來就像這樣:

t(o, n) = b / o + (1 - b / o) / n
記住,現在程式的不可並行化部分佔了 b / o 的時間,所以,可並行化部分就佔了 1 - b / o 的時間。

如果 b 為 0.1,o 為 2,n 為 5,計算看起來就像這樣:

t(2,5) = 0.4 / 2 + (1 - 0.4 / 2) / 5

= 0.2 + (1 - 0.4 / 2) / 5

= 0.2 + (1 - 0.2) / 5

= 0.2 + 0.8 / 5

= 0.2 + 0.16

= 0.36

到目前為止,我們只用阿姆達爾定律計算了乙個程式或演算法在優化後或者並行化後的執行時間。我們也可以使用阿姆達爾定律計算加速比(speedup),也就是經過優化後或者序列化後的程式或演算法比原來快了多少。

如果舊版本的程式或演算法的執行時間為 t,那麼增速比就是:

speedup = t / t(o , n);
為了計算執行時間,我們常常把 t 設為 1,加速比為原來時間的乙個分數。公式大致像下面這樣:

speedup = 1 / t(o,n)
如果我們使用阿姆達爾定律來代替 t(o,n),我們可以得到下面的公式:

speedup = 1 / ( b / o + (1 - b / o) / n)
如果 b = 0.4, o = 2, n = 5, 計算變成下面這樣:

speedup = 1 / ( 0.4 / 2 + (1 - 0.4 / 2) / 5)

= 1 / ( 0.2 + (1 - 0.4 / 2) / 5)

= 1 / ( 0.2 + (1 - 0.2) / 5 )

= 1 / ( 0.2 + 0.8 / 5 )

= 1 / ( 0.2 + 0.16 )

= 1 / 0.36

= 2.77777 ...

上面的計算結果可以看出,如果你通過乙個因子 2 來優化不可並行化部分,乙個因子 5 來並行化可並行化部分,這個程式或演算法的最新優化版本最多可以比原來的版本快 2.77777 倍。

雖然阿姆達爾定律允許你並行化乙個演算法的理論加速比,但是不要過度依賴這樣的計算。在實際場景中,當你優化或並行化乙個演算法時,可以有很多的因子可以被考慮進來。

記憶體的速度,cpu 快取,磁碟,網絡卡等可能都是乙個限制因子。如果乙個演算法的最新版本是並行化的,但是導致了大量的 cpu 快取浪費,你可能不會再使用 xn 個 cpu 來獲得 xn 的期望加速。如果你的記憶體匯流排(memory bus),磁碟,網絡卡或者網路連線都處於高負載狀態,也是一樣的情況。

我們的建議是,使用阿姆達爾定律定律來指導我們優化程式,而不是用來測量優化帶來的實際加速比。記住,有時候乙個高度序列化的演算法勝過乙個並行化的演算法,因為序列化版本不需要進行協調管理(上下文切換),而且乙個單個的 cpu 在底層硬體工作(cpu 管道、cpu 快取等)上的一致性可能更好。

簡單粗暴的阿姆達爾定律

技術 於生活,技術又改變了生活。從生活中的例子說起 要完成拖地和燒開水這麼乙個工作,假設燒開水需要花費 2分鐘,拖地需要2分鐘,各佔總時間的50 為了趕時間,我叫上朋友一塊幫忙,因為燒開水的時間不為人所能控制,因此增派人手能做的工作只能是打掃衛生,此時完成整項工作可提公升的速度為 可提公升效率倍數 ...

阿姆達爾定律以及古斯塔夫森定律乾貨

阿姆達爾定律 amdahl 加速比定義 加速比 優化前系統耗時 優化後系統耗時 tn t1 f 1 n 1 f f序列比例 1 f 並行比例 n處理器個數 加速比 t1 tn 優化前耗時 優化後耗時 1 f 1 n 1 f 結論 增加cpu數量並不一定能起到有效的作用,提高系統內可並行的模組比重,合...

成功三大定律 荷花定律 金蟬定律 竹子定律

關於成功,有很多定律,比較有名的就是荷花定律 竹子定律和金蟬定律。他們都有共同的意義 成功,需要厚積薄發,要忍受煎熬,要耐得住寂寞,堅持,堅持,再堅持,直到最後成功的那一刻。荷花定律 乙個池塘裡的荷花,每一天都會以前一天的2倍數量在開放。如果到第30天,荷花就開滿了整個池塘。請問 在第幾天池塘中的荷...