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

时间:2013-09-16 02:09:21

标签: r asynchronous parallel-processing

我想知道是否可以使用R中的一个并行处理后端来做(可能不是)。我尝试了一些谷歌搜索,然后什么也没做。

我目前遇到的一般问题:

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

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

2 个答案:

答案 0 :(得分:6)

为了扩展Dirk的答案,我建议您使用" snow" parallel包中的API。 mcparallel函数似乎是完美的(如果您不使用Windows),但由于它使用{{fork函数执行图形操作,它不能很好地工作。 1}}。 " 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))
}

因此,您只需使用sendCall提交任务,然后使用recvResult等待结果。以下是Dirk建议使用bigmemory包的示例。

你可以创建一个&#34;大矩阵&#34;使用big.matrixas.big.matrix等功能。您可能希望有效地执行此操作,但我只是使用z转换矩阵as.big.matrix

library(bigmemory)
big <- as.big.matrix(z)

现在,我将创建一个群集,并使用bigdescribe将每个工作人员连接到attach.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))

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

要在第一个群集工作者上呼叫persp,我们使用sendCall

parallel:::sendCall(cl[[1]], function() {persp(big[]); NULL}, list())

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

r1 <- parallel:::recvResult(cl[[1]])

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

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

clusterEvalQ(cl[1], persp(big[]))

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

答案 1 :(得分:4)

R是,并且将保持单线程。

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