matlab中的並行方法與理解(2):parfor中的變量類型

轉載至: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之間會進行通信,要注意大量數據傳輸帶來的性能下降。尤其對於廣播變量,如果較大可嘗試變爲切片變量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章