参考类的并行计算

时间:2013-12-06 18:12:59

标签: r parallel-processing reference-class

我有一个相当大的对象列表,我想并行应用一个复杂的函数,但我当前的方法使用了太多的内存。我认为参考类可能会有所帮助,但使用mcapply修改它们似乎不起作用。

该函数修改了对象本身,因此我用新的对象覆盖原始对象。由于该对象是一个列表,我只修改了它的一小部分,我希望R的复制修改语义可以避免生成多个副本;然而,在运行它时,似乎并不是我正在做的事情。这是我一直使用的基本R方法的一个小例子。它正确地将余额重置为零。

## make a list of accounts, each with a balance
## and a function to reset the balance
foo <- lapply(1:5, function(x) list(balance=x))
reset1 <- function(x) {x$balance <- 0; x}
foo[[4]]$balance
## 4 ## BEFORE reset
foo <- mclapply(foo, reset1)
foo[[4]]$balance
## 0 ## AFTER reset

似乎使用引用类可能有用,因为它们是可变的,并且在使用lapply时它确实按照我的预期执行;余额重置为零。

Account <- setRefClass("Account", fields=list(balance="numeric"),
                       methods=list(reset=function() {balance <<- 0}))

foo <- lapply(1:5, function(x) Account$new(balance=x))
foo[[4]]$balance
## 4
invisible(lapply(foo, function(x) x$reset()))
foo[[4]]$balance
## 0

但是当我使用mclapply时,它没有正确重置。请注意,如果您使用的是Windows或mc.cores=1,则会调用lapply

foo <- lapply(1:5, function(x) Account$new(balance=x))
foo[[4]]$balance
## 4
invisible(mclapply(foo, function(x) x$reset()))
foo[[4]]$balance
## 4

发生了什么事?如何并行使用Reference Classes?有没有更好的方法来避免不必要的对象复制?

1 个答案:

答案 0 :(得分:2)

我认为分叉进程虽然可以访问工作区中的所有变量,但一定无法更改它们。这有效,但我还不知道它是否会改善内存问题。

foo <- mclapply(foo, function(x) {x$reset(); x})
foo[[4]]$balance
## 0