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

R中矩阵(或光栅)的并行求和,r,matrix,raster,r-raster,parallel-foreach,R,Matrix,Raster,R Raster,Parallel Foreach,我有一长串大矩阵(或光栅),我想并行求和。输出应该是一个矩阵。我使用.combine='+'函数尝试了foreach,该函数可以工作,但它似乎只在一个线程上工作,因此没有加速。有什么建议吗?谢谢 matrix.list <- list() for(i in 1:10000) matrix.list[[i]] <- matrix(1,nrow=100,ncol=100) library(foreach) library(doMC) registerDoMC(cores=2) mat

我有一长串大矩阵(或光栅),我想并行求和。输出应该是一个矩阵。我使用
.combine='+'
函数尝试了
foreach
,该函数可以工作,但它似乎只在一个线程上工作,因此没有加速。有什么建议吗?谢谢

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]]

matrix.list您的问题是,您只能并行执行
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
set.seed(42)

n您的问题是,您只能并行执行
矩阵。列表[[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
set.seed(42)

完全正确。我有600000个大小为7200x3600的矩阵,它们是稀疏的,但我不想使事情复杂化不是并行解决方案而是
Reduce(+',matrix.list)
运行速度大约是上述代码的18倍。当然,它只在一个核心上运行。它在并行循环后运行。所有并行操作都是列表提取。如果你想利用并行化,你应该分块进行矩阵加法。准确地说。我有600000个大小为7200x3600的矩阵,它们是稀疏的,但我不想使用com复制内容不是并行解决方案,但是
Reduce(+',matrix.list)
的运行速度大约是上述代码的18倍。当然,它只在一个内核上运行。它在并行化循环之后运行。所有并行操作都是列表提取。如果你想利用并行化,你应该分块进行矩阵加法。