我在办公室使用的计算机最近升级为四核计算机,这对我来说是一种祝福,因为有时我需要使用R做一些显式循环,结果基于一些逻辑规则,除了明确的循环之外,我无法弄清楚如何解决这个问题。
对于某些背景信息,有时候我有大约10000-20000行,我需要查看2列,并根据它们的值和一些逻辑规则来为新列生成值。
我正在尝试使用doSNOW
软件包来更好地利用未使用的CPU电源,我根据here中的示例编写了如下的演示脚本:
library(doSNOW)
# rm(list=ls())
cl<-makeCluster(2) # I have two cores
registerDoSNOW(cl)
table <- data.frame(a=rnorm(1000),b=rnorm(1000))
process <- function(table)
{for (loop in (1:nrow(table)))
{table[loop,"c"] <- with(table[loop,], a*b)
assign("table",table,envir=.GlobalEnv)
}
}
system.time(process(table))
system.time(foreach(j=1:2 ) %dopar% process(table))
stopCluster(cl)
我正在使用带有ATOM CPU的上网本试试这个,但结果很奇怪:
system.time(process(table))
user system elapsed
2.336 0.028 2.308
system.time(foreach(j=1:2 ) %dopar% process(table))
user system elapsed
0.160 0.032 3.646
使用doSNOW之后,结果所需的时间甚至比不使用doSNOW更长,我想知道这是我的ATOM上网本的问题,还是我在代码中做错了什么?
谢谢!
答案 0 :(得分:6)
据我所知,在您的示例中,您在没有snow
的情况下运行一次函数,在snow
运行两次。并行运行流程会增加额外开销,尤其是当您添加foreach
的基础架构时。因此,每次执行的平均时间少于串行运行时的平均时间,但是当你分开时,你不能指望相同的总时间。
所以你说“结果比不使用doSNOW更长”是不正确的。事实上,如果你第二次运行第一次,则需要几乎两倍的时间。所以snow
确实提高了性能。
这是一个公平的比较:
system.time(for(i in 1:2) process(table))
system.time(foreach(j=1:2 ) %dopar% process(table))
以这种方式思考:假设你有两个人可以在1分钟内独立完成一项任务。假设如果一个人执行多个任务,则会产生额外的开销。但如果你要求他们独立工作,他们需要更长的时间才能将他们的成果汇总在一起。如果你要求一个人完成两项任务,则需要2分钟。如果你要求每个人分开工作,那么总共花费的时间会超过1分钟,因为他们需要在最后进行沟通。
答案 1 :(得分:2)
首先,在一台机器上使用多核比使用雪更好;它利用了可以使用管道代替套接字的事实,fork所需的时间也比初始化进程要小。
现在,这也是为什么并行版本在您的上网本上运行时间更长的原因;切换到并行评估是不可避免的时间成本,它可以支配多个线程的收益。随着工作时间的延长,这段时间将变得微不足道,您将获得加速。
答案 2 :(得分:0)
减速的部分原因还可能是由于您最有可能使用单核CPU(除非您有更新的双核Atom)。在这种情况下,您正在运行R而不使用foreach()函数,但是在尝试并行运行的过程中会增加一些开销。我的建议是试试你办公室的那个,看看那里发生了什么。