在R中,mcparallel()
包中的parallel
函数在每次调用时都会向工作人员发送新任务。例如,如果我的机器具有N(物理)核心,并且我分叉2N任务,则每个核心开始运行两个任务,这是不可取的。我希望能够开始在N个工作人员上运行N个任务,然后,当每个任务完成时,将下一个任务提交给现在可用的核心。是否有捷径可寻?
我的任务需要不同的时间,因此不能选择在批量N中分叉任务串行。可能有一些解决方法,例如检查活动核心的数量,然后在它们成为时提交新任务免费,但有人知道一个简单的解决方案吗?
我已经尝试设置cl <- makeForkCluster(nnodes=N)
,确实设置了N个内核,但mcparallel()
不会使用它们。实际上,似乎没有办法将cl
提供给mcparallel()
。后者有一个选项mc.affinity
,但目前还不清楚如何使用它,它似乎没有做我想要的东西(根据文档,它的功能取决于机器)。
答案 0 :(得分:1)
你至少有两种可能性:
如上所述,您可以使用mcparallel的参数&#34; mc.cores&#34;或者&#34; mc.affinity&#34;。 在AMD平台上&#34; mc.affinity&#34;因为两个核共享相同的时钟,所以是优选 例如,FX-8350有8个内核,但内核0具有与内核1相同的时钟。如果仅为2个内核启动任务,最好将其分配给内核0和1而不是0和2。&#34; mc.affinity&#34;这样做。价格正在减少负载平衡。
&#34; mc.affinity&#34;存在于最新版本的软件包中。请参阅changelog以了解何时介绍。
您也可以使用操作系统工具设置亲和力,例如: &#34;使用taskset&#34;:
/ usr / bin / taskset -c 0-1 / usr / bin / R ...
在这里,您可以使脚本仅在核心0和1上运行。
请记住Linux编号,其核心从&#34; 0&#34;开始。包并行符合R的索引,第一个核心是核心编号1。
答案 1 :(得分:0)
我建议并行使用包含此功能的更高级别功能,而不是试图强制执行低级功能来执行您想要的操作。
在这种情况下,尝试将您的任务编写为单个函数的不同参数。然后,您可以使用mclapply()将mc.preschedule参数设置为TRUE,并将mc.cores参数设置为您希望一次使用的线程数。每次任务完成并且线程关闭时,将创建一个新线程,对下一个可用任务进行操作。
即使每个任务使用完全不同的代码,您也可以创建一个函数列表并将其传递给包装函数。例如,以下代码一次执行两个函数。
f1 <- function(x) {x^2}
f2 <- function(x) {2*x}
f3 <- function(x) {3*x}
f4 <- function(x) {x*3}
params <- list(f1,f2,f3,f4)
wrapper <- function(f,inx){f(inx)}
output <- mclapply(params,FUN=calling,mc.preschedule=TRUE,mc.cores=2,inx=5)
如果需要,您可以使params列出一系列列表,包括要传递给每个函数的各种参数以及函数定义。我经常使用这种方法处理不同长度的各种任务,效果很好。
当然,可能是您的各种任务只是对同一个函数的不同调用,在这种情况下,您可以直接使用mclapply而无需编写包装函数。