R中的并行计算(如果在foreach%dopar%中的语句)

时间:2018-02-22 23:28:35

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

我想按组(i)以if语句为条件更新我的四个变量(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语句。有人可以帮忙吗?

由于

1 个答案:

答案 0 :(得分: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似乎不是非常耗时,我认为加速的唯一希望是在并行部分使用极端分块

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
  }

这为每个工作者使用一个任务来减少开销。这是一项重要的技术,但在这种情况下,我仍然不确定它是否会在顺序运行方面给你带来不错的性能。