R中的并行计算(if语句在foreach %dopar%)
Parallel computing in R (if statement in foreach %dopar%)
我想根据 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 语句。有人可以帮忙吗?
谢谢
"if" 语句不是问题所在。问题是 workers 不能直接更新 master 上的变量。 workers 只能计算发送给 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
}
这使用每个工作人员一个任务来减少开销。这是一项重要的技术,但我仍然不确定在这种情况下它是否会给你带来超过 运行 的良好性能。
我想根据 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 语句。有人可以帮忙吗?
谢谢
"if" 语句不是问题所在。问题是 workers 不能直接更新 master 上的变量。 workers 只能计算发送给 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
}
这使用每个工作人员一个任务来减少开销。这是一项重要的技术,但我仍然不确定在这种情况下它是否会给你带来超过 运行 的良好性能。