您的问题是您只能matrix.list[[i]]
并行执行并且[[
列表非常快。该.combine
操作由主进程在所有并行任务完成后完成。
您应该将列表分成如下块:
set.seed(42)
n <- 1e3
matrix.list <- replicate(n, matrix(rnorm(1),nrow=1000,ncol=1000), simplify = FALSE)
system.time({
matrix.sum_s <- Reduce("+", matrix.list)
})
#user system elapsed
#1.83 1.25 3.08
library(foreach)
library(doParallel)
ncl <- 4
cl <- makeCluster(ncl)
registerDoParallel(cl)
system.time({
matrix.sum_p <- foreach(x = split(matrix.list, (seq_len(n) - 1) %/% (n/ncl)),
.combine='+') %dopar%
{Reduce("+", x)}
})
#user system elapsed
#6.49 35.97 46.97
stopCluster(cl)
all.equal(matrix.sum_s, matrix.sum_p)
#[1] TRUE
当然,并行化版本仍然比简单地使用Reduce
. 为什么?因为+
是一个快速的低级 ( .Primitive
) 函数。foreach
大部分时间都花在复制几 GB 的密集矩阵上。