当编写一个嵌套循环时,外部循环需要是顺序的,而内部循环通过一个非常简单的对象依赖于先前的迭代,有没有办法减少会话之间多次通信的开销?
这是一个使用doMC
and的示例foreach
:
library(doMC)
library(tictoc)
registerDoMC(3)
tic()
a <- runif(100)
for(i in seq_len(333)){
a <- foreach(j = 1:100, .combine = c) %dopar% {
sqrt(a[j])*sqrt(max(a))
}
}
toc()
#> 7.669 sec elapsed
tic()
a <- runif(100)
for(i in seq_len(333)){
a <- foreach(j = 1:100, .combine = c) %do% {
sqrt(a[j])*sqrt(max(a))
}
}
toc()
#> 5.224 sec elapsed
由reprex 包(v0.3.0)于 2019-07-22 创建
因为内部循环中的计算非常简单,所以创建多个会话和传输数据所引入的开销使得并行版本比顺序版本慢。
在分析代码后,正如预期的那样,时间差主要来自mcfork
,但由于计算非常简单并且仅由于a
向量而在调用之间有所不同,我想知道是否有一种方法可以使会话在foreach
调用之间持续存在并且只发送每次调用之间的a
向量(我认为这应该比分叉整个会话要快得多)。
有没有办法通过会话分叉结构来实现doMC
?是否有另一个并行后端能够提供这种解决方案(使会话在任务之间发生微小变化时持续存在)?