將R代碼提速:使用foreach package做併行運算(parellel computing)

當使用R做計算,常常以五萬次為單位的時候,就會開始有點不耐煩,在思考如何提高自己代碼的速度,通常這種計算都會“慢”在某個loop中,通常就是做個t.test或是wilcoxon.test之類的。此時就可以考慮把代碼稍微修改,加入並行(parellel)的概念於其中,這時候可以參考使用foreach這個apckage,(在計算量小的時候,就不用牛刀小試,反而會變慢,因為一開始程序會先分推等等並行前的處置,且最後你還會需要寫代碼把資料合起來成自己想要的格式,通常都是把list變成一個data.frame)。
當然傳統基本的apply, lapply, sapply, eapply, mapply, rapply等都可以用來將這類的任務解決,但本質上這些函數依舊是單核單線程在運算的,而這邊介紹的foreach package則可以支援多核以及在叢集電腦上的多node計算。
在foreach裡面的函數,多為binary operator的形式,最簡單的使用方式,是直接將其替代原本的loop寫法:
#最基本的用法就如同for loop
x <- foreach ( i = 1:3) %do% sqrt(i)</div>
#其支援多個variable同時來迭代
x <- foreach(a = 1:3, b=rep(10, 3)) %do% ( a + b )
#可以使用curly brace, 裡頭可以包更複雜的運算
x <- foreach(a= 1:3, b= rep(10 ,3)) %do% {</div>
a + b
}

#使用.combine 選項,可以將運算的複雜度提高
x <- foreach(i = 1:3, .combine=‘c’) %do% exp(i)
x <- foreach( i = 1:3, .combine=‘cbind’) %do% rnorm(4)</div>
#cfun為使用自訂函數
x <- foreach( i = 1:3, .combine=‘cfun’, .multicombine=TRUE) %do% rnorm(4)

基本上使用%do%可以在loop上更多元的操作,而foreach最強大的其實是他並行的運算指令,其實就把%do%改成%dopar%就可以了,不過其實foreach本身是有一些缺欠的,比如他內部跟操作系統中線程的處理,是使用fork而非exec,所以在並行中在指令中間暫時性的variable時,就會出現一些問題,這部分會有另一個package來幫其補齊不足(doParellel package)

PS:當combine pipe使用時,有可能會造成ram需求大升,造成問題!

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s