R 并行共享内存对象(Windows)

Posted

技术标签:

【中文标题】R 并行共享内存对象(Windows)【英文标题】:R parallel shared memory object (windows) 【发布时间】:2016-06-17 03:10:34 【问题描述】:

我有一个大数据表。每个并行进程都从中读取数据,处理数据并返回一个小得多的 data.table。我不希望将大 DT 复制到所有进程,但似乎 foreach 包中的 %dopar% 函数必须复制。

有没有办法让所有进程(在 Windows 中)共享对象?也就是说,使用foreach以外的包。

示例代码

library(doParallel)
cluster = makeCluster(4)
registerDoParallel(cluster)

M = 1e4 # make this larger 
dt = data.table(x = rep(LETTERS, M), y = rnorm(26*M))
res = foreach(trim = seq(0.6, 0.95, 0.05), .combine = rbind) %dopar% 
  dt[, .(trimmean = mean(y, trim = trim)), by = x][, trim := trim]

(我对在不使用并行的情况下在 data.table 中执行此操作的更好方法不感兴趣。这只是为了说明子进程需要读取所有数据以进行处理,但永远不要更改它的情况)

【问题讨论】:

***.com/questions/31575585/… 这就是我得到foreach 必须复制的信息的地方。我正在寻找其他可能性 我通常使用 snow 进行并行编码,并且没有遇到内存问题,所以如果我在这里感到困惑,请告诉我。在您的代码中,dt 在 foreach 的每次迭代中都会被更改,因此我发布的链接需要被复制并更改然后返回。听起来如果您将操作的结果分配给另一个对象,它不会被每个进程复制,而只会被读取。现在我不确定这将如何与 data.table 改变结构的行为一起工作......也许尝试相同的任务 dplyr 并分配给不同的对象以查看是否存在差异。 @AdamMccurdy, dt 在子进程中没有改变,它只是从中读取。第一个 [] 返回一个新的 data.table,然后在第二个 [] 中修改新的。 【参考方案1】:

由于 R 不是多线程的,因此并行工作程序被实现为各种并行编程包中的进程。进程的特点之一是它们的内存受到其他进程的保护,因此程序必须使用特殊机制在不同进程之间共享内存,例如内存映射文件。由于 R 没有对任何此类机制的直接内置支持,因此编写了诸如“bigmemory”之类的包,允许您创建可以在不同进程之间共享的对象。不幸的是,“data.table”包不支持这样的机制,所以我认为没有办法做你想做的事。

请注意,在 Posix 操作系统(例如 Mac OS X 和 Linux)上,进程和分叉的子进程之间可以“只读”共享内存,因此您可以使用“doMC”做您想做的事后端,但这当然不适用于 Windows。

【讨论】:

以上是关于R 并行共享内存对象(Windows)的主要内容,如果未能解决你的问题,请参考以下文章

R语言并行计算中的内存控制

多处理中的共享内存对象

CUDA 并行扫描算法共享内存竞争条件

使用 numpy 数组和共享内存并行化 python 循环

Windows共享内存示例

Windows进程通信-共享内存空间