dopar foreach(运行并行 for 循环)

普罗米修斯

这个问题与在多核上运行 for 循环特别相关。我正在尝试学习如何使用并行内核运行代码。实际代码有些复杂,所以我在这里重新创建一个非常基本和稀释的代码请注意,此示例仅用于说明目的,而不是实际代码。

library(parallel)
library(foreach)
library(doParallel)

#Creating a mock dataframe
Event_ID = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3)
Type=c("A","B","C","D","E","A","B","C","D","E","A","B","C","D")
Revenue1=c(24,9,51,7,22,15,86,66,0,57,44,93,34,37)
Revenue2=c(16,93,96,44,67,73,12,65,81,22,39,94,41,30)
z = data.frame(Event_ID,Type,Revenue1,Revenue2)
#replicates z 5000 times
n =5000
zz=do.call("rbind", replicate(n, z, simplify = FALSE))
zz$Revenue3 = 0

#################################################################
#   **foreach, dopar failed attempt**
#################################################################
cl=parallel::makeCluster(14,type="PSOCK") #I have 8 core 16 threads but use 14 here. Please edit this accordingly.
registerDoParallel(cl)
home1 = function(zz1){
  foreach(i=1:nrow(zz1), .combine = rbind) %dopar% {
    zz1[i,'Revenue3'] = sqrt(zz1[i,'Revenue1'])+(zz1[i,'Revenue2'])
  }
  return(zz1)
}

zzz = home1(zz1=zz)
stopCluster(cl) 

#################################################################
#Non parallel implementation
#################################################################
home2 = function(zz2){
  zz3=zz2
  for (i in 1:nrow(zz3)){
    zz3[i,'Revenue3'] = sqrt(zz3[i,'Revenue1'])+(zz3[i,'Revenue2'])
  }
  return(zz3)
}
zzzz=home2(zz2=zz)

我创建了一个数据框并尝试使用 foreach 和 dopar 但它似乎不起作用。接下来我提供代码的非并行版本的实现。但是,并行版本对我不起作用。我得到的输出 df 与输入矩阵相同。我意识到我可能犯了一个基本错误,但我没有足够的经验来弄清楚究竟是什么错误。任何帮助将不胜感激。

PS我确实意识到我的非并行版本不是最佳的,可以改进,但这是一个例子。

奥利弗

首先请注意,当覆盖现有 data.frames 中的值时,使用parallel, doParallelorforeach并行运行会有些限制。当通过这个包执行并行化时,正在启动一个并行运行的 R 会话,一个工作程序,它执行计算,以某种方便的形式返回执行的任何结果。这意味着除非提供(使用 .export 或作为函数参数),否则这些工作会话不包含原始会话中的任何对象。futurepromises并且ipc封装可以允许异步处理,同时在一些简单的成本修改原始会话内的变量。

请注意,由于每个会话将使用一个单独的内核,因此使用比内核更多的会话会降低整体性能。

至于实现本身,您希望如何进行并行化取决于您的计算需要什么以及您想要返回哪种格式。如果要执行简单的行式计算,可以使用以下内容:

library(iterators)
cl=parallel::makeCluster(4) #I have 8 core 16 threads but use 14 here. Please edit this accordingly.
registerDoParallel(cl)
stopCluster(cl)
home1 <- function(zz1){
  output <- foreach(x = iter(zz1, by = "row"), .combine = rbind) %dopar% {
    x[["Revenue3"]] <- sqrt(x[["Revenue1"]]) + x[["Revenue2"]]
    x
  }
  output
}
zzz <- home1(zz1=zz)
stopCluster(cl)

请注意,我在这里使用了 Iterator 结构,它可用于高效地迭代行/列。如果这是您正在寻找的计算类型,我建议采用矢量化方法,因为这将大大提高性能。

zz[["Revenue3"]] <- sqrt(zz[["Revenue2"]) + zz[["Revenue1"]]

后者在我的小型 4 核笔记本电脑上大约快 13000 倍。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在foreach dopar循环中绘制

来自分类Dev

R在HPC MPIcluster上运行foreach dopar循环

来自分类Dev

保存foreach dopar循环的多个输出

来自分类Dev

保存foreach dopar循环的多个输出

来自分类Dev

%dopar%foreach循环内写入CSV的安全方法

来自分类Dev

使用dopar的foreach循环不会在R中返回任何变量

来自分类Dev

R 中的并行计算(foreach %dopar% 中的 if 语句)

来自分类Dev

r - 列表之间的嵌套 %dopar% 循环

来自分类Dev

使用foreach和%dopar%输出所需的结果

来自分类Dev

“无限”异步并行foreach循环

来自分类Dev

Foreach 循环中的并行处理

来自分类Dev

并行运行bash for循环

来自分类Dev

与超时并行运行循环

来自分类Dev

并行循环以不同的间隔运行

来自分类Dev

尝试使用并行时,R中的%dopar%无法正常工作

来自分类Dev

根据函数的参数进行函数调用%do%与%dopar%(foreach)

来自分类Dev

foreach和dopar返回NULL而不是所需的答案

来自分类Dev

无关的嵌套foreach,外部有%dopar%和内部%do%

来自分类Dev

R foreach%dopar%:将结果导出到主R流程

来自分类Dev

在并行foreach循环中使用source()

来自分类Dev

并行IO绑定(网络)ForEach循环

来自分类Dev

在并行foreach循环中分配

来自分类Dev

Pthreads PHP:并行执行Foreach循环

来自分类Dev

在R中并行运行for循环

来自分类Dev

查询重新并行运行循环脚本

来自分类Dev

JavaFx与GUI并行运行While循环

来自分类Dev

并行循环

来自分类Dev

并行For与For循环

来自分类Dev

仅在软件包描述中导入foreach时如何使用%dopar%