【问题标题】:Parallel computing in R (if statement in foreach %dopar%)R 中的并行计算(foreach %dopar% 中的 if 语句)
【发布时间】:2018-02-22 23:28:34
【问题描述】:

我想根据 if 语句按组 (i) 更新我的四个变量(Z1、Z2、IVtmp$differror1、IVtmp$differror2)。

foreach(i=unique(IVtmp$scidx)) %dopar% {
  numerator=sum(P1new[IVtmp$scidx==i])+sum(P2new[DATA$scid==i])
  denominator=sum(P1old[IVtmp$scidx==i])+sum(P2old[DATA$scid==i])
  probab=exp(numerator-denominator)

  if (runif(1)<probab){
    Z1[DATA$scid==i]=e1new[DATA$scid==i]
    Z2[DATA$scid==i]=e2new[DATA$scid==i]
    IVtmp$differror1[IVtmp$scidx==i]=differror1new[IVtmp$scidx==i]
    IVtmp$differror2[IVtmp$scidx==i]=differror2new[IVtmp$scidx==i]
    change=change+1
  } else{
    Z1[DATA$scid==i]=e1old[DATA$scid==i]
    Z2[DATA$scid==i]=e2old[DATA$scid==i]
    IVtmp$differror1[IVtmp$scidx==i]=differror1old[IVtmp$scidx==i]
    IVtmp$differror2[IVtmp$scidx==i]=differror2old[IVtmp$scidx==i]
  }
}

但似乎我无法在 foreah 循环中执行 if 语句。有人可以帮忙吗?

谢谢

【问题讨论】:

  • 谢谢史蒂夫。那么,我应该在代码中添加什么?

标签: r if-statement parallel-processing parallel-foreach


【解决方案1】:

“if”语句不是问题。问题是工作人员不能直接更新主服务器上的变量。 worker 只能计算发送给 master 的值,而 master 必须用这些值更新自己的变量。

我认为并行运行这个问题不会获得良好的性能,但你可以试试这个:

library(doSNOW)
nw <- 4  # choose something reasonable for your computer
cl <- makeSOCKcluster(nw)
registerDoSNOW(cl)
iv <- unique(IVtmp$scidx)

probab <-
  foreach(i=iv, .combine='c') %dopar% {
    numerator=sum(P1new[IVtmp$scidx==i])+sum(P2new[DATA$scid==i])
    denominator=sum(P1old[IVtmp$scidx==i])+sum(P2old[DATA$scid==i])
    exp(numerator-denominator)
  }

for (i in iv) {
  if (runif(1)<probab[i]){
    Z1[DATA$scid==i]=e1new[DATA$scid==i]
    Z2[DATA$scid==i]=e2new[DATA$scid==i]
    IVtmp$differror1[IVtmp$scidx==i]=differror1new[IVtmp$scidx==i]
    IVtmp$differror2[IVtmp$scidx==i]=differror2new[IVtmp$scidx==i]
    change=change+1
  } else{
    Z1[DATA$scid==i]=e1old[DATA$scid==i]
    Z2[DATA$scid==i]=e2old[DATA$scid==i]
    IVtmp$differror1[IVtmp$scidx==i]=differror1old[IVtmp$scidx==i]
    IVtmp$differror2[IVtmp$scidx==i]=differror2old[IVtmp$scidx==i]
  }
}

这会并行计算probab,然后按顺序更新数据结构。为此,我将probab 转换为向量。

由于计算 probab 似乎不是很耗时,我认为您唯一希望加快速度的是在并行部分使用 extreme chunking

library(itertools)
probab <-
  foreach(ivchunk=isplitVector(iv, chunks=nw), .combine='c') %dopar% {
    p <- double(length(ivchunk))
    for (i in ivchunk) {
      numerator=sum(P1new[IVtmp$scidx==i])+sum(P2new[DATA$scid==i])
      denominator=sum(P1old[IVtmp$scidx==i])+sum(P2old[DATA$scid==i])
      p[i] <- exp(numerator-denominator)
    }
    p
  }

这使用每个工人一个任务来减少开销。这是一项重要的技术,但我仍然不确定在这种情况下它是否会给您带来比顺序运行更好的性能。

【讨论】:

  • 谢谢史蒂夫。它确实有所改善。只是并行计算的另一个一般问题。我应该请求多少核心?是不是越多越好?
  • @BobbyWChung detectCores 是一个很好的起点,但有时您应该使用更少(在计算机上完成其他工作或内存不足),有时您可以使用更多(如果任务是'不受 CPU 限制)。最好的办法是运行一些基准测试。
  • 谢谢你,史蒂夫!
猜你喜欢
  • 2013-08-17
  • 2020-05-17
  • 2012-11-10
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 1970-01-01
相关资源
最近更新 更多