在R parallel :: mcparallel中,是否有可能限制任何时候使用的内核数量?

时间:2013-04-25 15:45:49

标签: r parallel-processing

在R中,mcparallel()包中的parallel函数在每次调用时都会向工作人员发送新任务。例如,如果我的机器具有N(物理)核心,并且我分叉2N任务,则每个核心开始运行两个任务,这是不可取的。我希望能够开始在N个工作人员上运行N个任务,然后,当每个任务完成时,将下一个任务提交给现在可用的核心。是否有捷径可寻?

我的任务需要不同的时间,因此不能选择在批量N中分叉任务串行。可能有一些解决方法,例如检查活动核心的数量,然后在它们成为时提交新任务免费,但有人知道一个简单的解决方案吗?

我已经尝试设置cl <- makeForkCluster(nnodes=N),确实设置了N个内核,但mcparallel()不会使用它们。实际上,似乎没有办法将cl提供给mcparallel()。后者有一个选项mc.affinity,但目前还不清楚如何使用它,它似乎没有做我想要的东西(根据文档,它的功能取决于机器)。

2 个答案:

答案 0 :(得分:1)

你至少有两种可能性:

  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以了解何时介绍。

  2. 您也可以使用操作系统工具设置亲和力,例如: &#34;使用taskset&#34;:

    / usr / bin / taskset -c 0-1 / usr / bin / R ...

    在这里,您可以使脚本仅在核心0和1上运行。

  3. 请记住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而无需编写包装函数。