天天看點

matlab中的并行方法與了解(2):parfor中的變量類型parfor關鍵字的使用parfor中的變量類型worker配置注意事項

轉載至:http://blog.csdn.net/caozhk/article/details/38234293?utm_source=tuicool&utm_medium=referral

通常消耗最多計算資源的程式往往是循環。把循環并行化,或者優化循環體中的代碼是最常用的加快程式運作速度的思路。

Matlab提供了parfor關鍵字,可以很友善的在多核機器或叢集上實作并行計算。

parfor關鍵字的使用

由for關鍵字引導的循環通常為串行運作,如果改為parfor則可以由多個worker以并行方式執行。

parfor可以将n次循環分解為獨立不相關的m部分,然後将各部分分别交給一個worker執行。

循環執行的結果應該與n次循環執行的順序無關。

parfor中的變量類型

簡約變量

一般parfor中各次循環對應的運算應該互相獨立,但簡約操作可以在多次循環内同時對一個變量操作。這種變量稱為簡約變量。例如下方代碼中a就是簡約變量。

a = 0;

for i = 1:1000

a = a+i;

end

簡約操作包括+ - * .* & | [,] [;] {,} {;} min max union intersect。

同一個parfor循環對簡約變量的操作必須一緻,即必須是同一種簡約操作符。而且與操作符的相對位置也必須一緻。

簡約變量指派表達式應該滿足結合律和交換律。* [] {}底層有特殊處理保證結果的正确性。

切片變量(sliced)

parfor中可能需要讀取或寫入parfor之外的矩陣,讀取寫入位置與循環變量相關。這樣就需要向worker傳輸大量的資料。

矩陣如果被Matlab識别為切片變量,則資料可以分段傳輸到各worker,提高傳輸效率。

切片變量矩陣的大小是不可在parfor中改變的,且為了保證Matlab識别正确,每次循環中隻能讀取由同一個索引值索引的切片,如a[i] a[i+1]同時出現則a不被識别為切片變量。

循環變量(loop)

如上例中的i,表示目前循環的id。

廣播變量(broadcast)

在parfor之前指派,在parfor内隻進行讀取操作,不能再parfor之内對其指派。若在parfor以内對廣播變量指派,則會顯示“the variable xxxx in a parfor cannot be classified.”

臨時變量(temporary)

作用域局限于parfor内,parfor結束後不存在。不影響parfor之前聲明的同名變量。

各種變量區分的例子

下例中,parfor中的tmp是臨時變量,parfor結束後tmp的值依然是5,不受臨時變量的影響。

broadcast是廣播變量,每次循環中的值不變。

redued是簡約變量,Matlab對其的值将分段由各worker計算後送回主程序處理。

sliced為切片變量,資料傳輸有優化提升。

i為循環變量。

tmp = 5;
    broadcast = 1;
    reduced = 0;
    sliced = ones(1, 10);
    parfor i = 1:10
      tmp = i;
      reduced = reduced + i + broadcast;
      sliced(i) = sliced(i) * i;
    end
           

worker配置

在運作程式之前,需要配置worker。否則如前文所說,parfor循環将以普通for循環的形式運作,無法并行。

單機配置

使用matlabpool指令可以開啟關閉本機的并行計算池。
matlabpool n指令可以打開n個worker。
matlabpool open configname按照指定配置打開,預設配置為local。
程式運作結束後,應該使用matlabpool close關閉worker。
配置項的修改可以通過Parallel -> Manage Cluster Profile完成。
           

n的選擇:

如果有c個cpu核心,通常可以設定為c。如果是遠端伺服器,為防止伺服器響應卡頓,可以設定為c-1。對于計算密集型程式,超線程帶來的性能提升幾乎為0,可以設定為核心數,而不是線程數。

注意事項

循環次數n最好能整除以worker個數m,否則部分worker會配置設定較多的循環,造成一部分worker閑置一段時間,降低了并行性。

并行運作時各個worker之間會進行通信,要注意大量資料傳輸帶來的性能下降。尤其對于廣播變量,如果較大可嘗試變為切片變量。

繼續閱讀