使用doSNOW加速R中的显式循环

lok*_*art 1 parallel-processing r

我在办公室使用的计算机最近升级为四核计算机,这对我来说是一种祝福,因为有时我需要使用R做一些显式循环,结果基于一些逻辑规则,我可以'除了明确的循环之外,弄清楚如何解决这个问题.

对于某些背景信息,有时候我有大约10000-20000行,我需要查看2列,并根据它们的值和一些逻辑规则来为新列生成值.

我正在尝试使用该doSNOW软件包来更好地利用未使用的CPU电源,我已根据此处的示例编写了如下的演示脚本:

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)
Run Code Online (Sandbox Code Playgroud)

我正在使用带有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 
Run Code Online (Sandbox Code Playgroud)

在使用doSNOW之后,结果所需的时间比不使用doSNOW更长,我想知道这是我的ATOM上网本的问题,还是我在代码中做错了什么?

谢谢!

Sha*_*ane 6

据我所知,在你的例子中,你运行函数一次没有snow,两次运行snow.并行运行流程会增加额外开销,尤其是在添加基础架构时foreach.因此,每次执行的平均时间少于串行运行时的平均时间,但是当你分开时,你不能指望相同的总时间.

所以你说"结果甚至比不使用doSNOW更长"是错误的.事实上,如果你第二次运行第一次,则需要几乎两倍的时间.所以snow确实提高了性能.

这是一个公平的比较:

system.time(for(i in 1:2) process(table))
system.time(foreach(j=1:2 ) %dopar% process(table))
Run Code Online (Sandbox Code Playgroud)

可以这样想:假设你有两个人可以在1分钟内独立完成一项任务.假设如果一个人执行多个任务,则会产生额外的开销.但如果你要求他们独立工作,他们需要更长的时间才能将他们的成果汇总在一起.如果你要求一个人完成两项任务,则需要2分钟.如果你要求每个人分开工作,那么总共需要花费1分多钟,因为他们需要在最后进行沟通.