R中矩阵(或栅格)的并行求和

时间:2016-09-07 02:37:44

标签: r matrix raster r-raster parallel-foreach

我有一长串大型矩阵(或栅格),我想并行加总。输出应该是一个矩阵。我使用foreach函数尝试了.combine='+',这看起来很有效。但是看起来.combine只适用于一个线程,所以没有加速。有什么建议?感谢

matrix.list <- list()
for(i in 1:10000) matrix.list[[i]] <- matrix(1,nrow=100,ncol=100)

library(foreach)
library(doMC)
registerDoMC(cores=2)

matrix.sum <- foreach(i=1:10000,.combine='+') %dopar% matrix.list[[i]]

1 个答案:

答案 0 :(得分:0)

您的问题是,您只能并行执行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的密集矩阵。