使用MATLAB并行計算功能提高多核系統(tǒng)性能
典型數(shù)值計算問題
為了舉例說明這兩種方法,我們使用MATLAB 測試一個有關(guān)Girko圓定律的假設(shè)。Girko圓定律的內(nèi)容是:一個N×N的隨機矩陣(它的元素服從正態(tài)分布)的特征值位于半徑為 的圓內(nèi)。假設(shè)Girko圓定律能被修改應(yīng)用到奇異值上。這個假設(shè)是合理的因為奇異值是一個變換了的矩陣的特征值。首先我們用MATLAB代碼實現(xiàn)Girko圓定律的一個實例:
N = 1000;
plot(eig(randn(N)) / sqrt(N), ‘.’);
這段代碼運行后得到圖1,圖上每個點代表復(fù)平面上一個特征值。注意所有的特征值都位于半徑為1 ,圓心在軸的原點的圓內(nèi),特別指出的是結(jié)果與Girko圓定律是一致的,特征值的幅值沒有超過矩陣維數(shù)的平方根。
圖1 大小為1000的隨機矩陣的特征值在半徑為sqrt(1000)的圓內(nèi)
為了將Girko定律應(yīng)用到奇異值分解上,我們用MATLAB生成隨機矩陣,然后估算它們的奇異值,看是否能基于數(shù)值計算闡明這個假設(shè)。我們用任意變量N計算max(svd(randn(N)))的值,然后在結(jié)果中尋找規(guī)律,而這個規(guī)律是可以用奇異值分解的理論解釋的。
通過下面的循環(huán)產(chǎn)生正規(guī)隨機矩陣,并計算它們的奇異值:
y = zeros(1000,1);
for n = 1:1000
y(n) = max(svd(randn(n)));
end
plot(y);
在單核計算機上運行這段循環(huán)代碼時需要15分鐘多的時間。為了減少計算時間,我們用線程和并行 for循環(huán)在多核計算機上運行這段循環(huán)代碼,然后再來比較性能結(jié)果。
使用線程
線程是在多核計算機上進行并行計算的軟件解決方案,但是需要記住的一點是多線程和多核處理器不是同一個概念。通常線程的數(shù)量和多核的數(shù)量一致時性能是最好的,但是也有線程比核少的情況。我們將通過實驗去確定對于我們的計算所需的最佳的線程的個數(shù)。
運行上面的代碼,并通過MATLAB界面屬性窗口或者使用maxNumCompThreads()函數(shù)去調(diào)節(jié)線程的個數(shù)。圖2 顯示了不同線程數(shù)量對應(yīng)的結(jié)果。除了時間,還有加速情況和并行效率。前者是多核執(zhí)行時間與單核執(zhí)行時間的比率,理想地,我們期望在N個核上能達到N倍。后者是加速倍數(shù)與核的個數(shù)的比率,理想地,我們期望能達到100%。
線程個數(shù) |
運行循環(huán)所需時間 |
加速倍數(shù) |
效率 |
1 |
902.6 |
1.00 |
100% |
2 |
867.2 |
1.04 |
52% |
3 |
842.3 |
1.07 |
35% |
4 |
862.3 |
1.05 |
26% |
圖2 不同線程數(shù)量對應(yīng)的代碼性能
結(jié)果呈現(xiàn)混合型的特點。使用線程確實能提高計算的速度,但是在我們的例子,只有對svd()的調(diào)用是被并行計算的。這是因為MATLAB所支持的線程是有限制的:用戶不能決定代碼的哪部分進行并行運算。
一方面,我們使用多核在不改變代碼的情況下加快了計算的速度。另一方面,當(dāng)增加內(nèi)核而并沒有減少執(zhí)行時間時就意味著是對成本的浪費。這個時候,我們需要另一種并行運算方法。
使用并行for循環(huán)
Parfor循環(huán),即并行for循環(huán),在簡單計算中有大量循環(huán)語句時是非常有用的。使用Parfor需要并行計算工具箱的支持。圖3 是用Parfor語句和前面代碼的對比。
y = zeros(1000,1); for n = 1:1000 y(n) = max(svd(randn(n))); end plot(y); |
y = zeros(1000,1); parfor n = 1:1000 y(n) = max(svd(randn(n))); end plot(y); |
Labs數(shù)量 |
運行循環(huán)所需時間 |
加速倍數(shù) |
效率 |
1 |
870.1 |
1.00 |
100% |
2 |
487.0 |
1.79 |
89% |
3 |
346.2 |
2.51 |
83% |
4 |
273.9 |
3.17 |
79% |
圖4 不同的lab數(shù)量對應(yīng)的代碼性能
從結(jié)果可以看出,對于此奇異值分解的計算,無論從加速情況還是效率,parfor的性能是優(yōu)于多線程的。
不細究代碼實現(xiàn)的細節(jié),也有必要解釋使用parfor帶來的好處。例子中的代碼最顯著的特征是每個循環(huán)是獨立的。獨立性的特征使得parfor的應(yīng)用很簡單也很高效。使用parfor留給系統(tǒng)的唯一任務(wù)是分配循環(huán)任務(wù)到核執(zhí)行并獲取結(jié)果用于其他的運算。
值得說明的一點是parfor在隨機數(shù)產(chǎn)生的問題上。在parfor循環(huán)中使用諸如randn()函數(shù)產(chǎn)生的矩陣與for循環(huán)中使用類似函數(shù)產(chǎn)生的矩陣并不一致,因為parfor循環(huán)的是已經(jīng)被預(yù)定了的。在絕大多情況下,這種差異完全是可以接受的。
使用parfor有它的優(yōu)點,但也有其局限性。例如,如果循環(huán)之間相互依賴,而且這種依賴能夠通過代碼分析得到,那么執(zhí)行parfor循環(huán)就會得到錯誤的結(jié)果。如果這種依賴關(guān)系沒有檢測到,那么就會得到不正確的結(jié)果。下面的代碼說明了這樣的問題:
total = 0;
A = zeros(1000, 1);
parfor i = 1:100
total = total + i; % OK: this is ...
...a known reduction operation
A(i+1) = A(i) + 1; % error: ... ...loop iterations are dependent
end
利用parfor很容易計算total的表達式,但是對于第二個表達式,由于A(i+1)依賴于前一次循環(huán)得到的A(i),所以用parfor計算會產(chǎn)生問題。
讓我們來更進一步地看看每次循環(huán)發(fā)生了什么:
Iteration 1: i = 1
A(2) = A(1) + 1 = 0 + 1 = 1
Iteration 2: i = 2
A(3) = A(2) + 1 = 1 + 1 = 2
Iteration 3: i = 3
A(4) = A(3) + 1 = 2 + 1 = 3
通過以上分析我們可以用下面的parfor循環(huán)的代碼得到跟前面同樣結(jié)果的代碼:
parfor i = 1:10
A(i+1) = i;
end
擴展并行計算
MATLAB已經(jīng)支持幾種并行方法,其他的方法將逐漸在高版本中實現(xiàn)。
我們相信未來計算機將有越來越多的核??偸菦]過幾年核的個數(shù)就翻倍,也意味著計算能力的翻倍。但是要利用好這種硬件的優(yōu)勢就需要正確的軟件,而寫正確的軟件就需要正確的軟件開發(fā)工具。MATLAB便旨在實現(xiàn)這種需求。
________________________________________
所需產(chǎn)品
-
MATLAB
-
Parallel Computing Toolbox
資源與示例
-
Using parfor to Run Loops in Parallel
-
Parallel Programming in MATLAB
文章
-
Eigenvalues and Condition Numbers of Random Matrices. Alan Edelman. Ph.D. thesis, Massachusetts Institute of Technology, May 1989.
-
Language Design for an Uncertain Hardware Future. Roy Lurie. HPCwire, September 28, 2007
-
Multiple Processors and Multiple Cores. Cleve Moler. The MathWorks News & Notes, June 2007
Parfor循環(huán)在labs上執(zhí)行,labs之間是能夠交互的。像線程一樣,labs在處理器核上執(zhí)行,但是labs的數(shù)量并不一定與核的數(shù)量相匹配。另不同于線程,labs互相之間是不共享存儲單元的。所以,它們能夠運行在聯(lián)網(wǎng)的獨立的計算機上。但是,在我們的例子中,我們僅需要知道并行運算工具箱使得parfor有效地工作在一個多核系統(tǒng)上。每個核或本地worker能主導(dǎo)一個lab。
問題自然就出現(xiàn)了:改變代碼值得嗎?在我們的例子中,改變代碼是值得的因為下面的表格清楚地表明了使用parfor的好處。圖3 左邊:原來的代碼 右邊:用parfor實現(xiàn)的循環(huán)語句