あなたの問題は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 の密行列をコピーすることにほとんどの時間を費やしています。