經常用matlab處理大型數據,有時某些數據處理起來可能要幾天甚至更久。如果算法已經到最優,那么提高速度的最后方法就是從硬件下手了。在這個什么都開始並行的年代,matlab也提供了並行計算的功能,甚至能用GPU加速。matlab貌似在2010a開始支持並行計算,引入了一個工具箱,叫做parallel computing toolbox.它的使用方法,可以從matlab的幫助獲得。
我現在對matlab並行的研究還只是冰山一角,只研究了它parfor的用法。可以再google中輸入matlab parfor,你將得到足夠多的資料來了解這是個什么東西,如果你耐心,建議去研究研究matlab 幫助中對parfor的說明。這里我只大概講一下parfor。parfor就是paralle+for,也就是並行的for循環,怎么個並行法?我理解就是,matlab會弄出幾個虛擬的小pc,一個算i=1:30部分循環,一個算i=50:80部分循環,再來一個算i=90:120部分循環,當然數字是我瞎編的,我是想說matlab將一個大循環分成小塊,然后這些小塊並行計算,最后再合在一起。這樣,有一個問題,因為普通的循環是從i=1算到i=100,一個接一個算,如果下一次循環要依賴上一次循環怎么辦?如果出現這種情況,那就不能用matlab的parfor了。用parfor的前提條件就是,循環的每次迭代獨立,不相互依賴。舉個簡單的例子,計算1+2+3...+100就可以用parfor,但是如果計算斐波那契數列的前100個數字,那就不能用parfor了。
parfor就先解釋到這里,其實它涉及到的東西遠不止這些,而且感覺很令人糾結,如果你的C++很好,那就直接用C++吧!如果你還是想用matlab做並行,那就可以繼續向下看看我的一些經驗。
首先我是做圖像處理的,1000多個圖像,如果直接算可能要算上1天,所以我想用matlab的並行。我們都知道數字圖像可以看成矩陣,我們經常用for循環里面再加一個for循環來處理,但是parfor循環不能嵌套。那么原來的
for i=1:N
for j=1:M
end
end
就必須改成
parfor i=1:N
for j=1:M
end
end
或者
for i=1:N
parfor j=1:M
end
end
但是,這都不是最好的方法,因為如果循環的次數太少,並行就顯現不出威力來,所以最好的方法是這樣:
for k=1:M*N
i=mod(k-1,M)+1 %行號
j=floor((k-1)/M)+1 %列號
end
要注意一點的是k是按照列來數的,也就是這樣
1 4 7
2 5 8
3 6 9
所以,行號和列號別算錯了。這樣其他代碼就可以不變了。
還需要注意的一點就是就是,如果對矩陣f的每個像素計算的點值要賦值給矩陣g。這個g要在循環外面聲明好,而且要固定大小,在parfor循環里面最好也是向量,而非矩陣。計算完成后再用vec2mat函數轉換為矩陣,這個函數之后,可能還需要個轉置才能得到你需要的結果。
至於提高的速度來講,我處理一個680*340的矩陣,用2核提高了2倍,用4核提高了6倍。
然后就是如何聲明你要開啟的核(通常來講就是你的Pc有幾個核就聲明幾個)?
首先在matlab命令行里輸入:matlabpool open local 4
然后它會提示你一些消息,開啟成功后就像以前一樣操作就行。不想用了就再輸入matlabpool close,關閉並行。
這些內容也可以寫到函數里面去,比如
function yourFun()
....
matlabpool('open','local',4); %最后一個參數是你要開啟的線程數
parfor i=1:N
...
end
matlabpool close
....
end
如果你的parfor怎么都通不了,或者速度變得更慢了,建議看matlab 幫助中的這一部分,看明白了,自然就有答案了: