交互式R中的异步命令调度

Sco*_*hie 6 parallel-processing asynchronous r

我想知道是否可以使用其中一个并行处理后端(可能不是)R.我尝试了一些谷歌搜索,没有任何结果.

我目前遇到的一般问题:

  • 我有一些大型物体需要大约半小时到达 load
  • 我想在数据上生成一系列图表(需要几分钟).
  • 我想在发生这种情况时继续对数据做其他事情(尽管不改变基础数据!)

理想情况下,我可以从交互式会话中调度命令,而不必等待它返回(所以我可以在等待渲染时继续做其他事情).这是可能的,还是这是一厢情愿的想法?

Ste*_*ton 6

为了扩展Dirk的答案,我建议您在parallel包中使用"snow"API .该mcparallel功能似乎是完美的(如果您不使用Windows),但由于它的使用它不能很好地执行图形操作fork."snow"API的问题在于它不正式支持异步操作.但是,如果你不介意使用非导出功能作弊,那么这很容易做到.如果查看代码clusterCall,可以了解如何异步提交任务:

> library(parallel)
> clusterCall
function (cl = NULL, fun, ...) 
{
    cl <- defaultCluster(cl)
    for (i in seq_along(cl)) sendCall(cl[[i]], fun, list(...))
    checkForRemoteErrors(lapply(cl, recvResult))
}
Run Code Online (Sandbox Code Playgroud)

因此,您只需使用sendCall提交任务,并recvResult等待结果.这是使用bigmemory包的示例,如Dirk所建议的那样.

您可以使用big.matrix或等函数创建"大矩阵" as.big.matrix.您可能希望有效地执行此操作,但我将z使用as.big.matrix以下命令转换矩阵:

library(bigmemory)
big <- as.big.matrix(z)
Run Code Online (Sandbox Code Playgroud)

现在我将创建一个集群并将每个工作者连接到big使用describeattach.big.matrix:

cl <- makePSOCKcluster(2)
worker.init <- function(descr) {
  library(bigmemory)
  big <<- attach.big.matrix(descr)
  X11()  # use "quartz()" on a Mac; "windows()" on Windows
  NULL
}
clusterCall(cl, worker.init, describe(big))
Run Code Online (Sandbox Code Playgroud)

除了附加到大矩阵之外,这还会打开每个工作人员的图形窗口.

要调用persp第一个集群工作者,我们使用sendCall:

parallel:::sendCall(cl[[1]], function() {persp(big[]); NULL}, list())
Run Code Online (Sandbox Code Playgroud)

这几乎立即返回,虽然可能需要一段时间才能出现情节.此时,您可以将任务提交给其他集群工作程序,或执行完全不相关的其他操作.只需确保在向同一工作人员提交另一个任务之前阅读结果:

r1 <- parallel:::recvResult(cl[[1]])
Run Code Online (Sandbox Code Playgroud)

当然,这一切都非常容易出错,而且一点都不漂亮,但你可以编写一些函数来简化它.请记住,这些非导出的功能可以随着R的任何新版本而改变.

请注意,通过对集群对象进行子集化来对特定工作人员或工作集执行任务是完全可能且合法的.例如:

clusterEvalQ(cl[1], persp(big[]))
Run Code Online (Sandbox Code Playgroud)

这将把任务发送给第一个工作人员而其他人什么也不做.但是,当然,这是同步的,因此在此任务完成之前,您无法对其他集群工作程序执行任何操作.我知道以异步方式发送任务的唯一方法就是作弊.


Dir*_*tel 4

R 是、并将继续是单线程的。

但可以共享资源。一种方法是在一个会话中加载大数据,将其分配给一个大内存对象,然后与同一机器上的其他 R 会话共享该对象的“句柄”。在一个具有足够内存(即所有数据需求的低倍数)的体面 Linux 机器上,这应该是相当容易的事情。