我试图解决为什么串行运行良好且在本地计算机(具有3个核心)上并行运行良好的进程在群集上的多个核心上运行时可能会减慢速度的原因。我无法做出最小的非工作示例,因为代码在本地工作得很好。
我修改了脚本以将每个工作人员的输出保存到文件中,然后我会聚集文件的大量文件 - 所以我不认为这是通信和聚合,除非我遗漏了什么。
这是我的输出。我为一个相当复杂的过程展示了一个包装器函数,然后在运行plyr
之前我自己运行一次:
> analyze_ = function(r){#wrapper function with error handling
+ sti = proc.time()
+ out<-tryCatch(analyze(r)
+ , error=function(e) e, finally=1+1)
+ if(inherits(out, "error")) {
+ out='error!'
+ print(paste("an error happened at",r[1],r[2]))
+ }
+ print(proc.time()-sti
+ }
>
> st = proc.time()
> x = analyze_(xygrid[1,])
[1] "Successfully did -0.25 100.25"
user system elapsed
8.282 0.008 8.286
然后我并行运行代码,一切都慢下来:
> nodes <- detectCores()
> nodes
[1] 24
> registerDoMC(nodes)
> output<-a_ply(xygrid,1,analyze_, .parallel=T)
[1] "Successfully did 0.25 102.25"
user system elapsed
9.292 0.042 221.954
[1] "Successfully did 0.25 10.25"
user system elapsed
9.298 0.039 221.994
[1] "Successfully did -0.25 102.75"
user system elapsed
9.313 0.054 222.808
[1] "Successfully did -0.25 102.25"
user system elapsed
9.328 0.043 222.832
[1] "Successfully did -0.25 104.25"
user system elapsed
9.250 0.032 223.761
[1] "Successfully did -0.25 103.75"
user system elapsed
9.258 0.038 223.786
可能导致此类行为的一些事情是什么?正如我所说,该功能会丢弃输出,在串行运行时保持基准速度,并在我的本地计算机上并行运行三个核心。
这是一个问题:为什么&#34;已经过去&#34;时间几乎是&#34;用户&#34;的准确24倍倍数。时间? (无论如何,&#34;用户&#34;时间是什么?)
编辑在回答评论中的问题时,这里是并行与串行中性能的正面比较。并行实际上更慢。
> system.time(analyze_(xygrid[1,]))
user system elapsed
8.223 0.005 8.250
>
> nodes <- detectCores()
> nodes
[1] 24
> registerDoMC(nodes)
>
> system.time(a_ply(xygrid[1:24,],1,analyze_, .parallel=F))
user system elapsed
197.666 0.072 197.762
>
> system.time(a_ply(xygrid[1:24,],1,analyze_, .parallel=T))
system elapsed
119.871 0.401 206.257
EDIT2 代码在登录节点上正常工作 - 每个作业连续6秒,并行24个作业需要12秒。那么计算节点一般与登录节点有何不同?
EDIT3
的解决
事实证明,我一直在我的shell脚本中使用ibrun
,它将作业发送到多个线程。但是,R使用名为&#34; thread parallelism&#34;的东西,其中并行后端从R内部调用,而不是从调用R作业的shell脚本调用。如果从批处理命令调用多个线程,则集群将使并行作业在每个核心中运行。因此速度是核心数量的粗略倍数。因此,故事的道德:只在共享资源系统上询问批处理系统中的一个线程,并让R处理使用的实际核心数。这个问题可能只与配备批处理系统的共享超级计算机有关。