R中不平等任务和进度条的最佳负载平衡

Optimal load balancing of unequal tasks and progress bars in R

我有 N 个任务,我希望在 R 中跨 M 个内核并行执行这些任务。这些任务的执行时间差异很大。幸运的是,我粗略地知道哪些任务会很慢,哪些会很快。我还有一个进度条,它会随着完成的任务数递增。

我想优化任务的顺序:

  1. 总计算时间最小化
  2. 进度条表示剩余时间,而不是剩余任务。

举个更实际的例子:

do_task <- function(x){
  Sys.sleep(x ** 2)
}

tasks <- 1:10

cl <- parallel::makeCluster(4)
pbapply::pboptions(use_lb = TRUE)
pbapply::pblapply(tasks, do_task, cl = cl)
parallel::stopCluster(cl)
rm(cl)

总处理时间为 6 分 32 秒,进度条开始移动很快,但随着任务花费的时间越来越长,进度条移动得非常慢。

或者从最长到最短:

tasks <- 10:1

这需要 2 分 20 秒,快多了。但是进度条开始的时候很慢,然后突然加快了。

我也试过交织任务。

tasks <- c(10,1,9,2,8,3,7,4,6,5)

这需要 3 分 20 秒,不是最快的,但确实提供了一个更平衡的进度条。

进一步研究发现this

这表明pbapply 中的负载平衡很差。他们举了一个我改编的例子

pb <- utils::txtProgressBar(max = 10, style = 3)
progress <- function(n) utils::setTxtProgressBar(pb, n)
opts <- list(progress = progress)
cl <- parallel::makeCluster(4)
doSNOW::registerDoSNOW(cl)
boot <- foreach::foreach(i = tasks, .options.snow = opts)
res_all <- foreach::`%dopar%`(boot, do_task(i))
parallel::stopCluster(cl)

此运行时间为 105 秒,接近最佳时间 100 秒,比我发现的任何其他方法都要好得多。进度条还是很参差不齐,但至少快了。