ann*_*ann 5 parallel-processing r parallel.foreach mclapply doparallel
这是出于好奇而提出的一般性问题。我正在使用该doParallel包进行并行计算。我使用这些包来进行模拟。
我观察到,当我使用foreach循环进行模拟时,Rstudio 中的当前使用内存急剧上升 (4+GiB),并且 Rstudio 有时崩溃。
现在我再次parallel::mclapply进行了相同的模拟,但令人惊讶的是没有问题,并且当前使用内存没有增加太多(10+MiB)。
我不明白代码内部发生了什么。我期待对上述过程的详细解释。
sessionInfo()因为我的 R 是
R version 4.2.1 (2022-06-23) -- "Funny-Looking Kid"
Copyright (C) 2022 The R Foundation for Statistical Computing
Platform: aarch64-apple-darwin20 (64-bit)
Run Code Online (Sandbox Code Playgroud)
操作系统是MacOS。
doParallel软件包版本 1.0.17。
RStudio 版本 2023.03.01。
假设我们正在尝试计算 Erdos-Renyi 图的边数。我试图每次模拟图形并存储每次模拟的边计数值。
代码如下
#ER random graph generator
src1 <- {"#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix ER_AdjMatGEN_cpp(int N, double p){
NumericMatrix temp(N,N);
for(int i=0; i< N; i++){
for(int j=0; j < i; j++){
temp(i,j) = R::rbinom(1,p);
temp(j,i) = temp(i,j);
}
}
return temp;
}"}
Run Code Online (Sandbox Code Playgroud)
Niter <- 10000
#________________
edgeCnt_result1 <- foreach(icount(Niter),
v = iter(function() ER_AdjMatGEN_cpp(10000, 0.3)),
.combine = "rbind") %dopar% {
sum(v)
}
#___________
edgeCnt_result1 <- do.call(rbind, mclapply(1:Niter, function(i) {v = ER_AdjMatGEN_cpp(N = 10000, 0.3)
return(sum(v))} , mc.cores = 7))
Run Code Online (Sandbox Code Playgroud)
当我尝试运行第一次迭代时,Rstudio 崩溃,但当我运行第二次迭代时,它运行正常。
您的mclapply()代码首先生成完整的Niter长列表,然后将do.call()其全部绑定在一起。结果向量只有一种分配。
foreach()另一方面,.combine当列表元素变得可用时,用于重新绑定列表元素,随着结果向量的增长迭代地重新分配它。
相反,请使用的.multicombine和.maxcombine参数foreach()。要模仿do.call(),请将第一个TRUE和第二个设置为Niter。
有关更详细的说明,请参阅https://rpubs.com/jimhester/rbind 。