R做并行计算
R本身雖然只能以單線程的方式運行與計算,但它有大量的包提供了方便而多樣的并行計算方式,支持包括SOCKET、MPI、PVM、NWS等等多種線程溝通方式。最流行最成熟的當然是MPI了,Rmpi包也因此相當受歡迎,在它的基礎上可以實現各種MPI支持的并行編程范式。但要論簡單易用,支持協議的多樣性,就得說說snow包及其簡化包裝版snowfall包了。snow支持上面提到的四種線程溝通協議,所以即使沒有安裝MPI或者對MPI了解不多,最基本的也可以直接使用SOCKET方式快速上手。而有了snowfall,更是使得并行化的計算變得如同平常編程一般的簡單。
由于這些包是為R而擴展的,所以跟R的矢量式編程思想能無縫地結合,只要你的程序已經用矢量化語言描述出來(比如R的apply系列函數或簡單矩陣運算),再移植到snowfall并行計算平臺幾乎就是0成本。
下面通過兩個簡單的函數來說明snowfall的使用及其性能。在運行測試函數之前都需要先載入snowfall包,即library(snowfall)
測試函數1:
foo <- function(i){cat(sprintf('log: item %s', i))return(2^i) } test.base <- function(){x = 1:10sfInit(parallel=TRUE, cpus=2, slaveOutfile='/tmp/snowfall.log')sfExport('foo')res = sfClusterApplyLB(x, fun='foo')sfStop()cat(unlist(res)) }這個函數說明了snowfall包的基本使用:
測試函數2:
mysort <- function(x){replicate(5, sort(x))return(sort(x)[1:10]) } test.apply <- function(cpus=4){M = matrix(rnorm(10000000), 100, 100000)print('sequence run:')print(system.time(x<-apply(M, 2, mysort)))t = Sys.time() # sfInit(parallel=TRUE, socketHosts=c(rep('balin',2), rep('dwalin',2)))sfInit(parallel=TRUE, cpus=cpus)print(sprintf('%s cpus to be used', sfCpus()))print('parallel time cost:')print(system.time(x<-sfApply(M, 2, mysort)))sfStop()print(paste('total parallel time cost:', Sys.time()-t)) }這個函數展示了一個實際的有一定負載量的計算過程。
測試函數2的性能測試如下:
- 非并行情況下,總耗時31秒多;
- 2 slave的情況下,總耗時22秒多;
- 4 slave的情況下,總耗時接近15秒。
- 補:在sfInit函數初始化時,設置type=’MPI’,使用MPI方式并行,4 slave情況下,比SOCKET方式稍慢,耗時17秒多。
即slave增加4倍時,計算時間減少一半。
轉載于:https://www.cnblogs.com/hukunyu/archive/2011/09/02/2163649.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
- 上一篇: C# 中奇妙的函数–6. 五个序列聚合运
- 下一篇: cursor_sharing用法