MATLAB 並行計算效率很低,怎麼辦?
01-23
最近在考慮把自己的一個演算法並行化,然後……我懶,不想用C+OPENMP之類的方式去實現,希望用matlab的parpool湊合一下。然後問題來了。這玩意效率低的我目瞪口呆,或者可能是設置有問題,具體見下。
測試代碼很簡單,計算兩個隨機生成的規模為3000*3000的矩陣乘法,重複20遍。並行時則是每個work負擔5次。為了消除交換數據的開銷,直接把兩個矩陣都保存成了composite形式,這樣各worker的工作等於是完全獨立了。然而並沒有什麼卵用。單線程代碼跑了8458.2ms,多線程代碼跑了7984.0ms,幾乎可以認為是沒有差別。而如果代碼改成這樣:其中A,B是隨機生成的矩陣,C,D是composite格式的副本tic; E=A*B;toctic;spmd F=C*D;end toc,那麼從原理上講,速度應該是一樣的,可是事實上spmd的耗時正好是4倍單線程(1692ms versus 421ms)。這就很奇怪了。作為驗證,我調取了單線程和多線程計算時的CPU負載圖。如下:
波峰的前半是由單線程計算引起的,後半是由spmd塊引起的。可見幾乎沒有什麼差別,雖然是parpool(4),但是從CPU負載上看幾乎沒什麼差別。這是怎麼回事呢?
因為這裡矩陣乘法本身就是多線程的,目前版本 MATLAB 大部分的內建數值計算函數也都是多線程的。
具體來說,MATLAB 的矩陣乘法在 intel CPU 上調用了 mkl 的多線程版本作為 BLAS
想更快的話可以考慮下 GPU 運算並行不一定更快,甚至會更慢,因為會有通訊成本。提速的方案有: 1 改進程序演算法,盡量降低時間複雜度2 用profiler計時,找到那個性能瓶頸
3 瓶頸用mex或Java改寫或網上找到替代品。
本人是做FDTD優化的,對matlab的並行運算折磨了很久。 具體到你的問題:1. 只有兩個3000*3000的矩陣,通信cost不是問題,非常小。2.matlab的矩陣乘法和所有點運算都是多線程優化的,所以你的spmd的耗時正好是4倍。3.對於一個3000*3000的矩陣運算,GPU運算比CPU快的不是一點半點的。以我的經驗,矩陣運算尺寸100*100~1000*1000是CPU與GPU的運算能力的相交點(我的筆記本的cpu i7 6770,GPU NV960M)。尺寸100一下果斷CPU+parfor,尺寸500以上,嘗試GPU。
4.對於你所需要的運算(隨機,矩陣乘法)已經是最基本的運算,不要指望能找到能優化的mex。
5.對於更普遍的問題,在運算中,我們經常需要其他的「常量」,如果這些常量比較大的話,是會嚴重影響parfor和GPU運算的。其中,parfor的comm cost 遠高於GPU。總結起來:大尺寸用GPU,小尺寸的複雜運算用parfor,基礎運算啥也不用最快。大規模矩陣運算?
ArrayFire +GPU+c++效率應該沒的說吧.
推薦閱讀:
※從並行計算的角度,MPI 與 OpenMP 的對比?
※為什麼超級計算機比集群貴?
※請問pcie x16/x8以及sli/cfx對運算卡性能的影響?
※有哪些好用的開源並行線性矩陣求解器?
※為什麼伺服器linux下用openmp結果比單線程還要慢?