R和并行内存为parallel :: mclapply

Cla*_*ley 9 macos r shared-memory

我试图通过并行执行在大约1000个项目列表上执行的昂贵操作来利用四核机器.

我目前正在使用R的parallel :: mclapply函数:

res = rbind.fill(parallel::mclapply(lst, fun, mc.cores=3, mc.preschedule=T))
Run Code Online (Sandbox Code Playgroud)

哪个有效.问题是,产生的任何其他子进程必须分配大块内存:

在此输入图像描述

理想情况下,我希望每个内核都可以从父R进程访问共享内存,因此当我增加mclapply中使用的内核数量时,我不会在内核限制之前达到RAM限制.

我目前对如何调试此问题感到茫然.每个进程访问的所有大型数据结构都是全局(当前).这是某种问题吗?

我确实将操作系统的共享内存最大设置增加到20 GB(可用RAM):

$ cat /etc/sysctl.conf 
kern.sysv.shmmax=21474836480
kern.sysv.shmall=5242880
kern.sysv.shmmin=1
kern.sysv.shmmni=32
kern.sysv.shmseg=8
kern.maxprocperuid=512
kern.maxproc=2048
Run Code Online (Sandbox Code Playgroud)

我认为这会解决问题,但问题仍然存在.

还有其他想法吗?

Kar*_*ner 5

Linux和macosx 在分叉时具有写复制机制,这意味着内存页面实际上没有被复制,而是在第一次写入之前共享. mclapply基于fork(),所以可能(除非你写入你的大共享数据),你看到的进程列表报告的内存不是实际的内存.

但是,在收集结果时,主进程必须为mclapply的每个返回结果分配内存.

为了进一步帮助您,我们需要了解您的有趣功能.


Dea*_*Vil 5

提示:R-devel Digest,第149卷,第22期可能发生了什么

Radford Neal从2015年7月26日开始的回答:

当mclapply分支以启动新进程时,该内存最初与父进程共享。但是,无论哪个进程写入一个内存页面,都必须对其进行复制。不幸的是,R的垃圾收集器会在完成完整的垃圾收集后写入每个对象以对其进行标记和取消标记,因此,即使实际上并没有改变很多R对象,每个过程中每个R对象也很可能会重复。 R程序的视图)。

  • 虽然此链接可以回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会变得无效。但无论如何,您的回答非常值得赞赏。谢谢 :) (2认同)