Mån*_*nsT 10 parallel-processing r
我第一次在R中进行并行化.作为第一个玩具示例,我试过了
library(doMC)
registerDoMC()
B<-10000
myFunc<-function()
{
for(i in 1:B) sqrt(i)
}
myFunc2<-function()
{
foreach(i = 1:B) %do% sqrt(i)
}
myParFunc<-function()
{
foreach(i = 1:B) %dopar% sqrt(i)
}
Run Code Online (Sandbox Code Playgroud)
我知道sqrt()执行速度太快,无法实现并行化,但我没想到的是,它foreach() %do%会比for()以下更慢:
> system.time(myFunc())
user system elapsed
0.004 0.000 0.005
> system.time(myFunc2())
user system elapsed
6.756 0.000 6.759
> system.time(myParFunc())
user system elapsed
6.140 0.524 6.096
Run Code Online (Sandbox Code Playgroud)
在我看过的大多数例子中,foreach() %dopar%都是比较foreach() %do%而不是for().由于foreach() %do%比for()我的玩具示例慢得多,我现在有点困惑.不知何故,我认为这些是构造for循环的等效方法.有什么不同?它们是否相同?是foreach() %do%始终慢?
更新:关于@Peter罚款回答,我更新myFunc如下:
a<-rep(NA,B)
myFunc<-function()
{
for(i in 1:B) a[i]<-sqrt(i)
}
Run Code Online (Sandbox Code Playgroud)
这for()有点慢,但并不多:
> system.time(myFunc())
user system elapsed
0.036 0.000 0.035
> system.time(myFunc2())
user system elapsed
6.380 0.000 6.385
Run Code Online (Sandbox Code Playgroud)
for将运行sqrtB次,可能每次丢弃答案.foreach但是,返回一个列表,其中包含循环体每次执行的结果.无论是以并行还是顺序模式(%dopar%或%do%)运行,这都会产生相当大的额外开销.
我通过运行以下代码来建立我的答案,该代码似乎由foreach插图确认,其中指出"foreach与for循环的不同之处在于它的返回值是值列表,而for循环没有值并且使用副作用传达其结果."
> print(for(i in 1:10) sqrt(i))
NULL
> print(foreach(i = 1:10) %do% sqrt(i))
[[1]]
[1] 1
[[2]]
[1] 1.414214
[[3]]
... etc
Run Code Online (Sandbox Code Playgroud)
更新:我从您更新的问题中看到,上述答案几乎不足以说明性能差异.所以我看了看源代码的foreach,可以看到,有很多事情!我还没有尝试准确理解它是如何工作的,但是do.R并且foreach.R表明即使在%do%运行时,foreach仍然会运行大部分配置,如果可能提供的%do%选项很大程度上允许您测试foreach代码而不必有一个并行后端配置和加载.它还需要支持更高级的嵌套和迭代工具foreach.
有在代码中的结果缓存,错误校验,调试和每次迭代的参数局部环境变量的创建引用(见函数doSEQ中do.R的例子).我想这就是你所观察到的差异.当然,如果你在循环中运行更复杂的代码(实际上会从类似的并行化框架中受益foreach),与它提供的好处相比,这种开销将变得无关紧要.
| 归档时间: |
|
| 查看次数: |
4199 次 |
| 最近记录: |