R system()进程总是使用相同的CPU,而不是多线程/多核

时间:2013-12-02 09:07:30

标签: multithreading r process multicore

在Linux 3.12.0上的R 3.0.2中,我使用system()函数来执行许多任务。如果我通过R系统在R system()之外的命令行执行它们,那么这些任务中的每一个都会产生预期的效果。

但是,当通过system()在R中执行它们时,每个任务都与主R进程中的同一个CPU绑定。

换句话说:

当通过RScript直接从Rash外部的bash shell启动时,每个任务都在自己的核心上运行(这是必要的)

当通过system()在R内部启动时,每个任务都在同一个核心上运行。没有多核共享。如果我有100个任务,那么它们都被困在一个核心上。

我无法弄清楚如何在R中生成一个进程,以便每个进程都使用自己的核心。

我正在使用一个简单的测试来消耗CPU周期,所以我可以使用top / htop来测量效果:

dd if=/dev/urandom bs=32k count=1000 | bzip2 -9 >> /dev/null

当这个简单的测试在R之外多次启动时,每次迭代都有自己的核心。但是当我在R:

中启动它时
system("dd if=/dev/urandom bs=32k count=2000 | bzip2 -9 >> /dev/null", ignore.stdout=TRUE,ignore.stderr=TRUE,wait=FALSE)

他们都被困在一个核心上。

这是在运行4个系统()

的同时/并发迭代之后的可视化

enter image description here

请帮助我,我需要告诉R启动新任务,每个任务都以自己的核心运行。

2013年12月4日更新:

我在Python中尝试使用它进行测试:

import thread
thread.start_new_thread(os.system,("/bin/dd if=/dev/urandom of=/dev/null bs=32k count=2000",))

我多次重复新线程,并且正如预期的那样一切正常(使用多个核心,每个线程一个)。

所以我认为在R中安装rPython包,并在R:

中尝试相同的操作
python.exec("import thread")
python.exec("thread.start_new_thread(os.system,('/bin/dd if=/dev/urandom of=/dev/null bs=32k count=2000',))")

不幸的是,即使在重复呼叫之后,它又被限制在单个核心。为什么从R执行时,所有启动的内容都限于单个内核?

2 个答案:

答案 0 :(得分:7)

关于@ agstudy的评论,你应该让parallel先行。在我的系统上,它使用多个核心:

f<-function(x)system("dd if=/dev/urandom bs=32k count=2000 | bzip2 -9 >> /dev/null", ignore.stdout=TRUE,ignore.stderr=TRUE,wait=FALSE)
library(parallel)
mclapply(1:4,f,mc.cores=4)

我自己会在评论中写这篇文章,但这篇文章太长了。我知道你说你已经尝试了parallel包,但我想确认你正确使用它。如果它不起作用,您能否确认非系统调用正确使用mclapply,如此?

a<-mclapply(rep(1e8,4),rnorm,mc.cores=4)

阅读您的评论,我怀疑您的pthreads Linux软件包已过时且已损坏。在我的系统上,我使用的是libpthread-2.15.so(不是2.13)。如果您使用的是Ubuntu,则可以使用apt-get install libpthread-stubs0获取最新信息。

另请注意,您应该使用parallel,而不是multicore。如果您查看parallel multicore,则会注意到他们已将工作纳入parallel


阅读下一组评论时,我必须坚持自2.14以来已经包含在R中的multicore而不是parallel。您可以在at the docs上阅读相关内容。

library(parallel) mcaffinity() # Should be c(1,2,3,4) for you. detectCores() # Should be 4 for you. 工作至关重要。我之前告诉过你,你可以直接从源代码编译它,但这不正确。我想重新编译它的唯一方法是从源代码编译R.

您还可以验证您的CPU亲和力是否设置正确?您还可以检查R是否可以检测核心数量?跑吧:

{{1}}

答案 1 :(得分:2)

我测试了跑步:

system("dd if=/dev/urandom bs=32k count=2000 | bzip2 -9 >> /dev/null", ignore.stdout=TRUE,ignore.stderr=TRUE,wait=FALSE)
system("dd if=/dev/urandom bs=32k count=2000 | bzip2 -9 >> /dev/null", ignore.stdout=TRUE,ignore.stderr=TRUE,wait=FALSE)
system("dd if=/dev/urandom bs=32k count=2000 | bzip2 -9 >> /dev/null", ignore.stdout=TRUE,ignore.stderr=TRUE,wait=FALSE)
system("dd if=/dev/urandom bs=32k count=2000 | bzip2 -9 >> /dev/null", ignore.stdout=TRUE,ignore.stderr=TRUE,wait=FALSE)

在Linux 2.6.32上使用R 3.0.2,在Linux 3.8.0上使用R 2.15.2。在这两种情况下,它占用4个CPU内核(如您所料)。

- 编辑 -

我在Virtual Box机器上安装了Linux 3.12,这里R 3.0.2也做了我的期望:占用4个CPU。它甚至在CPU之间慢慢徘徊 - 因此每个进程都不会粘在同一个CPU上,而是每隔一秒左右就会发生变化。

这让我相信你的系统是一些局部修改,迫使R只使用一个CPU。

根据您的描述,我猜测本地修改是在R而不是系统范围内(因为您的Python没有问题产生更多进程)。

修改可能仅限于您的用户,因此请创建一个新用户并尝试使用它。如果它适用于新用户,我们需要确定您的用户ID已安装的内容。

如果它对新用户不起作用,则可能是全局安装导致问题的R库。安装较旧的R版本并试一试。如果旧版本有效,则R 3.0.2安装可能已损坏。将其取下并重新安装。