有没有办法在这个 R 代码中进行并行处理?

Is there a way to do parallelism in this R Code?

我正在尝试学习 R 中的并行性。我编写了一个代码,其中有一个 50*50 的矩阵,其值从 1 到 250000。对于矩阵中的每个元素,我都在寻找其具有最低值的邻居价值。邻居也可以处于对角线位置。然后我用最低的邻居替换元素本身。 运行 此代码在我的计算机上花费的时间约为 4.5 秒。如果可以的话,谁能帮我使 for 循环并行?这是代码片段

start_time <- Sys.time()


myMatrix <- matrix(1:250000, nrow=500) # a 500 * 500 matrix from 1 to 250000


indexBound <- function(row,col) { # this function is to check if the indexes are out of bound
  if(row<0 || col <0 || row > 500 || col >500){
    return (FALSE)
  }
  else{
    return (TRUE)
  }
}


for(row in 1:nrow(myMatrix)){
  
  for(col in 1:ncol(myMatrix)){
    li <- list()
    if(indexBound(row-1,col-1)){
      li <- c(li,myMatrix[row-1,col-1])
     
    }
    if(indexBound(row-1,col)){
      li <- c(li,myMatrix[row-1,col])
     
    }
    if(indexBound(row-1,col+1)){
      li <- c(li,myMatrix[row-1,col+1])
      
    }
    if(indexBound(row,col-1)){
      li <- c(li,myMatrix[row,col-1])
    }
    if(indexBound(row-1,col+1)){
      li <- c(li,myMatrix[row,col+1])
      
    }
    if(indexBound(row+1,col-1)){
      li <- c(li,myMatrix[row+1,col-1])
      
    }
    if(indexBound(row+1,col)){
      li <- c(li,myMatrix[row+1,col])
    
    }
    if(indexBound(row+1,col+1)){
      li <- c(li, myMatrix[row+1,col+1])
     
    }
    min = Reduce(min,li) #find the lowest value from the list
    myMatrix[row,col] = min
  }
}
end_time <- Sys.time()

end_time - start_time



感谢您的回复。

您的脚本将生成一个所有元素都等于 2 的矩阵。如果这不是本意,您应该创建一个 myMatrix 的副本,以便在构建 li 时使用(在if 个陈述)。

我意识到这可能是探索并行化的人为示例,但对于 R,通常最好首先关注矢量化。向量化时,此操作可能足够快,以至于并行化实际上可能由于开销而变慢。例如,这是一个使用填充矩阵的矢量化解决方案(这不会给出所有 2,并且它仍然不包括 min 计算中的当前单元格):

library(matrixStats)

system.time({
  idxShift <- expand.grid(rep(list(-1:1), 2))[-5,] # don't include the current cell (0, 0)
  myMatrix <- matrix(nrow = 502, ncol = 502)
  myMatrix[2:501, 2:501] <- matrix(1:250000, nrow = 500)
  myMatrix <- matrix(rowMins(mapply(function(i,j) c(myMatrix[2:501 + i, 2:501 + j]), idxShift$Var1, idxShift$Var2), na.rm = TRUE), nrow = 500)
})

   user  system elapsed 
   0.03    0.00    0.03 

将其与使用 future.apply 的相同矢量化代码的并行版本进行比较:

library(future.apply)
plan(multisession)

system.time({
  idxShift <- expand.grid(rep(list(-1:1), 2))[-5,]
  myMatrix <- matrix(nrow = 502, ncol = 502)
  myMatrix[2:501, 2:501] <- matrix(1:250000, nrow = 500)
  myMatrix <- matrix(rowMins(future_mapply(function(i,j) c(myMatrix[2:501 + i, 2:501 + j]), idxShift$Var1, idxShift$Var2), na.rm = TRUE), nrow = 500)
})

future:::ClusterRegistry("stop")

   user  system elapsed 
   0.10    0.05    2.11 

如果我没有搞砸什么,并行解决方案会更慢,即使不包括 plan(multisession) 的时间也是如此。