【发布时间】:2015-05-20 15:08:31
【问题描述】:
我正在尝试将doMC 与foreach 和%dopar% 一起使用。这是函数:
doTheMath_MC <- function(st, end, nd) {
print(getDoParWorkers())
if (st > end) stop("end must be larger than st")
# Helper function from stackoverflow.com/a/23158178/633251
tr <- function(x, prec = 0) trunc(x * 10^prec) / 10^prec
# Function to use with foreach
fef <- function(i, j, num, trpi) {
if (num[j] >= num[i]) return(NULL)
val <- num[i]/num[j]
if (!tr(val, nd) == trpi) return(NULL)
return(c(i, j, tr(val, nd)))
}
# Here we go...
nd <- nd - 1
trpi <- tr(pi, nd)
num <- st:end
ni <- length(num)
ans <- foreach(i = 1:ni, .combine = rbind) %:%
foreach(j = 1:ni, .combine = rbind) %dopar% {
fef(i, j, num, trpi)
}
cat("Done computing", paste("EST", st, end, nd+1, sep = "_"), "\n")
if (is.null(ans)) return(NULL)
ans <- as.matrix(na.omit(ans)) # probably not needed in MC version
return(ans) # c("num", "den", "est", "eff")
}
我之前已经设置了核心,另一个函数调用了上面的函数(这个信息发布在下面,我认为不是问题)。 getDoParWorkers() 报告已按预期分配了 7 个内核。 cat 语句验证 2 个“循环”在输出范围内是否正常工作。但是,只使用了 1 个内核。有人知道为什么吗? Mac OSX 10.10.2 和 R 3.2 (2015-03-15 r67992)。最后,使用doParallel 控制一切都会得到相同的结果。
设置一切的步骤:
mn <- 1
mx <- 10000
jmp <- 1000
mc <- TRUE
if (mc) {
require("doMC")
registerDoMC(7)
}
st <- seq(mn -1, mx - jmp, jmp) + 1
end <- seq(mn - 1 + jmp, mx, jmp)
nd <- rep(1:15, each = mx/jmp) # watch the recycling
df <- data.frame(st = st, end = end, nd = nd)
for (i in 1:nrow(df)) {
findEsts(df$st[i], df$end[i], df$nd[i], MC = mc)
}
【问题讨论】:
-
运行时是否有任何警告输出?您之前是否能够在该计算机(和分区)上成功使用并行处理?
-
没有警告。
doMC中的bootMC示例运行正确。我从终端使用R CMD batch运行它。重启 R 没关系。谢谢。 -
我做了一些测试,我注意到当内部循环中的每次迭代需要更长的计算时间时,并行后端的使用更加充分。如果我不得不粗略猜测,它只会计算这样做是否有效。对于单个(非嵌套循环)也是如此。如果我是你,我会尝试并行运行外循环,然后正常运行内循环。
-
谢谢。我会试试的。我突然想到(虽然我无法入睡!)我写 fef 的方式可能是“去矢量化”过程,因此一次只完成一个计算。我认为这与您所说的相似。
-
我认为你是在正确的轨道上。当任务很短时,worker 使用的 CPU 时间很少,所以你只能看到 master 进程消耗的 CPU 时间。通过顺序执行内部循环,您可以使任务 CPU 密集度足够高,值得并行执行外部循环,然后工作人员将使用大量 CPU 时间。
标签: r foreach parallel-processing domc