Matlab的parfor並行編程
- 通常消耗最多計算資源的程序往往是循環。
把循環並行化。或者優化循環體中的代碼是最經常使用的加快程序執行速度的思路。
- Matlab提供了parforkeyword,能夠非常方便的在多核機器或集群上實現並行計算。
parforkeyword的使用
- 由forkeyword引導的循環通常為串行運行。假設改為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循環對簡約變量的操作必須一致。即必須是同一種簡約操作符。並且與操作符的相對位置也必須一致。
- 簡約變量賦值表達式應該滿足結合律和交換律。
* [] {}
底層有特殊處理保證結果的正確性。
切片變量
- parfor中可能須要讀取或寫入parfor之外的矩陣,讀取寫入位置與循環變量相關。這樣就須要向worker傳輸大量的數據。
- 矩陣假設被Matlab識別為切片變量,則數據能夠分段傳輸到各worker,提高傳輸效率。
- 切片變量矩陣的大小是不可在parfor中改變的。且為了保證Matlab識別正確。每次循環中僅僅能讀取由同一個索引值索引的切片。如
a[i] a[i+1]
同一時候出現則a不被識別為切片變量。
循環變量
- 如上例中的i,表示當前循環的id。
廣播變量
- 在parfor之前賦值,在parfor內僅僅進行讀取操作。
暫時變量
- 作用域局限於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。假設是遠程server,為防止server響應卡頓,能夠設置為
c-1
。對於計算密集型程序,超線程帶來的性能提升差點兒為0,能夠設置為核心數,而不是線程數。
注意事項
- 循環次數n最好能整除以worker個數m,否則部分worker會分配較多的循環,造成一部分worker閑置一段時間,減少了並行性。
- 並行執行時各個worker之間會進行通信。要注意大量傳輸數據帶來的性能下降。
尤其對於廣播變量。假設較大可嘗試變為切片變量。