在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个系统()
的同时/并发迭代之后的可视化
请帮助我,我需要告诉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执行时,所有启动的内容都限于单个内核?
答案 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安装可能已损坏。将其取下并重新安装。