2

有没有办法修改 R foreach 循环如何使用 doParallel 后端进行负载平衡?当并行化执行时间非常不同的任务时,可能会发生所有节点,但一个节点已完成任务,而最后一个节点仍有几项任务要做。这是一个玩具示例:

library(foreach)
library(doParallel)

registerDoParallel(4)

waittime = c(10,1,1,1,10,1,1,1,10,1,1,1,10,1,1,1)

w = iter(waittime)

foreach(i=w) %dopar% {
    message(paste("waiting",i, "on",Sys.getpid()))
    Sys.sleep(i)
}

基本上,代码注册了 4 个内核。对于每个循环i,任务是等待waittime[i]几秒钟。但是,因为默认情况下,foreach 循环中的负载均衡似乎是将任务总数拆分为长度为已注册核心数的集合,所以在上面的示例中,第一个核心接收所有带有waittime=的任务10,而其他 3 个收到waittime= 1 的任务,因此这 3 个核心将在第一个完成第一个之前完成所有任务。

有没有办法foreach()一次分配一个任务?即在上述情况下,我希望前 4 个任务分布在 4 个内核之间,然后每个下一个任务都分布到下一个可用内核。

谢谢。

4

2 回答 2

4

我自己没有测试过,但是后端doParallel提供了一个preschedule类似于mc.preschedule. mclapply()(参见doParallel 小插图的第 7 节。)

你可以试试:

mcoptions <- list(preschedule = FALSE)
foreach(i = w, .options.multicore = mcoptions)
于 2017-03-09T11:22:49.157 回答
1

很抱歉作为答案发布,但我没有足够的代表发表评论。您是否可以重写代码以使用 parLapplyLB 或 parSapplyLB?

parLapplyLB、parSapplyLB 是负载平衡版本,用于将 FUN 应用于 X 的不同元素需要相当多的时间,并且该函数是确定性的或不需要可重现的结果。

于 2017-03-09T09:37:05.763 回答