2017-06-16 20 views
0

我在R降雪包中使用sfApply进行并行计算。有32000个测试运行。代码在启动计算时工作正常,它会创建46个Rscript.exe进程,每个Rscript.exe的CPU使用率为2%。整体CPU使用率约为100%,并且结果不断写入磁盘。计算通常需要几十个小时。奇怪的是,Rscript.exe进程逐渐变为非活动状态(cpu usage = 0),并且相应的cpu也处于非活动状态。两天后,通过查看CPU使用情况,只有一半Rscript.exe处于活动状态,整体CPU使用率降至50%。但是,这项工作还很遥远。随着时间的推移,越来越多的Rscript.exe变得无效,这使得工作持续很长时间。我想知道是什么让进程和cpu核心处于不活动状态?R降雪并行,Rscript.exe随着时间的推移逐渐失效

我的电脑有46个逻辑核心。我在64位Windows 7中使用了Rstudio的R-3.4.0。以下“测试”变量是32000 * 2矩阵。我的功能是解决一些微分方程。

谢谢。

library(snowfall) 
    sfInit(parallel=TRUE, cpus=46) 
    Sys.time() 
    sfLibrary(deSolve) 
    sfExport("myfunction","test") 
    res<-sfApply(test,1,function(x){myfunction(x[1],x[2])}) 
    sfStop() 
    Sys.time() 
+0

内存使用情况如何?有足够的RAM可用吗?这里没有太多要走,但你可以尝试一次只运行几项任务,看看它们是否通过。开始增加任务的数量,直到遇到瓶颈。 –

+0

谢谢。 RAM可用,仅使用10G(总共64G)。我可以尝试,但问题是过程正在逐渐失去活性。任务正在继续,只是越来越少cpus。这就像在计算过程中让核心一个接一个睡着。 – yan

+0

对不起,我没有想法。也许你可以使用其他并行工具,比如'parallel'或'foreach'? –

回答

0

什么你所描述听起来很合理,因为snowfall::sfApply()使用snow::parApply()内部,你的数据(test)口吃了起来成(这里)46块,并将每个块出到46名[R工人之一。当工人完成大块工作时,没有更多的工作要处理,只剩下其他工人处理剩余的块。

你想要做的是将你的数据拆分成更小的块,这将导致每个工人平均处理多个块。我不知道,如果(想?)这是可能的降雪。并行包是R本身的一部分,取代了雪包(即降雪依赖),它提供了parApply()parApplyLB(),后者将块分割成最小尺寸,即每个数据元素(test)一个。有关详细信息,请参见help("parApply", package = "parallel")

future软件包(我是作者),为您提供了选择想要分割数据的选项。它不提供apply()版本,但可以使用lapply()版本(以及parApply()如何在内部工作)。例如,使用每个工人一个大块的例子是:

library("future") 
plan(multisession, workers = 46L) 

## Coerce matrix into list with one element per matrix row 
test_rows <- lapply(seq_len(nrow(test)), FUN = function(row) test[row,]) 

res <- future_lapply(test_rows, FUN = function(x) { 
    myfunction(x[1],x[2]) 
}) 

这是默认为

res <- future_lapply(test_rows, FUN = function(x) { 
    myfunction(x[1],x[2]) 
}, future.scheduling = 1.0) 

如果你想使每个工人在一次处理一行分裂数据(参见parallel::parApplyLB()),你这样做是:

res <- future_lapply(test_rows, FUN = function(x) { 
    myfunction(x[1],x[2]) 
}, future.scheduling = Inf) 

通过[1,天道酬勤]设置future.scheduling,你可以控制平均块大小是多大。例如,在future_lapply()返回之前,future.scheduling = 2.0将使每个工作进程平均有两个数据块。

相关问题