r - R中具有优先级的异步依赖期货
问题描述
这是一个典型的分析工作流程。
依次运行如下所示:
## some simple functions to mimic longer running models
m1 <- \() {
Sys.sleep(4*15)
"model 1 results"
}
m2 <- \() {
Sys.sleep(3*15)
"model 2 results"
}
m3 <- \() {
Sys.sleep(2*15)
"model 3 results"
}
process <- \(text) {
Sys.sleep(0.5 * 10)
sprintf("processed %s", text)
}
###### Approach 1 ~155.2 seconds --- sequential ######
start <- proc.time()
## model 1
m1res <- m1()
p1res <- process(m1res)
cat(p1res, fill = TRUE)
## model 2
m2res <- m2()
p2res <- process(m2res)
cat(p2res, fill = TRUE)
## model 3
m3res <- m3()
p3res <- process(m3res)
cat(p3res, fill = TRUE)
stop <- proc.time()
## total run time
stop - start
大约需要 155.2 秒。使用该future
软件包,我们可以加快速度。假设有 2 个 CPU。
###### Approach 2 ~102.7 seconds --- models not blocked but not optimal run ######
## load future package and setup a multisession with 2 workers
library(future)
plan("multisession", workers = 2)
start <- proc.time()
## fit models
p1res <- future({
model1 <- m1()
process(model1)
})
p2res <- future({
model2 <- m2()
process(model2)
})
p3res <- future({
model3 <- m3()
process(model3)
})
## present results
cat(value(p1res), fill = TRUE)
cat(value(p2res), fill = TRUE)
cat(value(p3res), fill = TRUE)
stop <- proc.time()
## total run time
stop - start
现在我们下降到 ~102.7 秒,但这仍然不是最佳的。理想情况下会发生的是:
- CPU 1:运行模型 1、进程模型 1、进程模型 2
- CPU 2:运行模型 2,运行模型 3,处理模型 3
###### Approach 3 ~82.7 seconds --- models not blocked but not optimal run ######
start <- proc.time()
## fit models
m1res %<-% m1()
m2res %<-% m2()
m3res %<-% m3()
## grab results
p1res %<-% process(m1res)
p2res %<-% process(m2res)
p3res %<-% process(m3res)
## present results
cat(p1res, fill = TRUE)
cat(p2res, fill = TRUE)
cat(p3res, fill = TRUE)
stop <- proc.time()
## total run time
stop - start
我们可以得到,现在只需要大约 82.7 秒。但是,代码不再以非常清晰的方式组织。分析 1 的所有内容都不再在一起了。
是否可以像方法 1 那样编写代码,将模型和后处理等放在一起,同时R
像第 3 方法一样运行它?伪代码如下所示:
m1res <- future({
m1()
}, priority = 1)
p1res <- future({
process(m1res)
}, priority = 2, dependson = "m1res")
m2res <- future({
m2()
}, priority = 1)
p2res <- future({
process(m2res)
}, priority = 2, dependson = "m2res")
本质上是某种作业/任务调度程序,可以在未来和优先级列表中构建依赖关系,以便:
(1)任务在可用时贪婪运行,只要依赖关系已经解决(2)如果有多个任务可用,高优先级任务优先于低优先级任务运行。
我尝试使用lazy = TRUE
选项future
来查看我是否可以将事情排队,但是在使用多会话时,您不能在另一个未来使用未解决的未来。
解决方案
推荐阅读
- javascript - 使用 cron.schedule 时避免事件记录在表中重复
- c# - 实体框架:如何启用迁移以从 sql 视图获取和保存数据?
- amazon-web-services - AWS Cognito - 记录最终用户活动以进行审计
- ios - 如何将json响应存储到变量中?
- r - 如何获取R中文本中的数字数量?
- c# - unity3d C# 中的 Kafka Consumer 集成
- c# - EF 将实体序列化为包含相关实体的 json 创建一个循环
- excel - 从单独的表中返回表中的值
- arrays - 如何根据一行中的值对 Swift 中的二维数组列进行排序?
- laravel - 如何在 Laravel 中检查日期验证规则中的年份