R 如何提高并行集群处理的速度

R 如何提高并行集群处理的速度,r,parallel-processing,cluster-computing,R,Parallel Processing,Cluster Computing,我是群集处理新手,可以就如何更好地准备数据和/或从parallel包调用函数提供一些建议。我已经看完了并行程序包的小插曲,所以对发生的事情有一个模糊的概念 我想要并行化的函数调用二维插值工具akima::interp。我的输入由3个矩阵(或向量——在R中都是相同的):一个包含一组采样点的x坐标,一个包含y坐标,一个包含“z”或数据值interp使用它在常规网格上生成插值数据,以便我可以(例如)绘制字段。设置好这3个项目后,我将它们切成“块”,并将它们送入clusterApply以逐块执行inte

我是群集处理新手,可以就如何更好地准备数据和/或从
parallel
包调用函数提供一些建议。我已经看完了
并行程序包
的小插曲,所以对发生的事情有一个模糊的概念

我想要并行化的函数调用二维插值工具
akima::interp
。我的输入由3个矩阵(或向量——在
R
中都是相同的):一个包含一组采样点的x坐标,一个包含y坐标,一个包含“z”或数据值
interp
使用它在常规网格上生成插值数据,以便我可以(例如)绘制字段。设置好这3个项目后,我将它们切成“块”,并将它们送入
clusterApply
以逐块执行
interp

我使用的是Windows7,i7CPU(8核)机器。以下是来自
Rprof
的输入数据集的摘要输出,该数据集具有1e6个点(1000x1000,如果您愿意),并映射到1000x1000输出网格

因此,我的问题是: 1) “非序列化”似乎占用了大部分时间。这是什么操作,如何减少? 2) 一般来说,由于每个worker都加载默认的
.Rdata
文件,因此,如果我首先将所有输入数据保存到
.Rdata
,这样就不需要将其传递给worker,是否会提高速度? 3) 还有什么我根本没有意识到的,我应该做的不同的事情吗

注意:
sin、atan2、cos、+、max、min
函数在我调用
clusterApply
之前执行

Rgames> summaryRprof('bigprof.txt')
$by.self
                   self.time self.pct total.time total.pct
"unserialize"         329.04    99.11     329.04     99.11
"socketConnection"      1.74     0.52       1.74      0.52
"serialize"             0.96     0.29       0.96      0.29
"sin"                   0.06     0.02       0.06      0.02
"atan2"                 0.04     0.01       0.06      0.02
"cos"                   0.04     0.01       0.04      0.01
"+"                     0.02     0.01       0.02      0.01
"max"                   0.02     0.01       0.02      0.01
"min"                   0.02     0.01       0.02      0.01
"row"                   0.02     0.01       0.02      0.01
"writeLines"            0.02     0.01       0.02      0.01

$by.total
                     total.time total.pct self.time self.pct
"mcswirl"                331.98    100.00      0.00     0.00
"clusterApply"           330.00     99.40      0.00     0.00
"staticClusterApply"     330.00     99.40      0.00     0.00
"FUN"                    329.06     99.12      0.00     0.00
"unserialize"            329.04     99.11    329.04    99.11
"lapply"                 329.04     99.11      0.00     0.00
"recvData"               329.04     99.11      0.00     0.00
"recvData.SOCKnode"      329.04     99.11      0.00     0.00
"makeCluster"              1.76      0.53      0.00     0.00
"makePSOCKcluster"         1.76      0.53      0.00     0.00
"newPSOCKnode"             1.76      0.53      0.00     0.00
"socketConnection"         1.74      0.52      1.74     0.52
"serialize"                0.96      0.29      0.96     0.29
"postNode"                 0.96      0.29      0.00     0.00
"sendCall"                 0.96      0.29      0.00     0.00
"sendData"                 0.96      0.29      0.00     0.00
"sendData.SOCKnode"        0.96      0.29      0.00     0.00
"sin"                      0.06      0.02      0.06     0.02
"atan2"                    0.06      0.02      0.04     0.01
"cos"                      0.04      0.01      0.04     0.01
"+"                        0.02      0.01      0.02     0.01
"max"                      0.02      0.01      0.02     0.01
"min"                      0.02      0.01      0.02     0.01
"row"                      0.02      0.01      0.02     0.01
"writeLines"               0.02      0.01      0.02     0.01
"outer"                    0.02      0.01      0.00     0.00
"system"                   0.02      0.01      0.00     0.00

$sample.interval
[1] 0.02

$sampling.time
[1] 331.98

调用
clusterApply
时,它首先向每个集群工作程序发送一个任务,然后等待每个工作程序返回相应的结果。如果还有更多任务要做,它将重复该过程,直到所有任务都完成

它用来等待特定工作进程的结果的函数是
recvResult
,它最终调用
unserialize
,从连接到该工作进程的套接字读取数据。因此,如果主进程将其大部分时间花在
取消序列化
,那么它将花费大部分时间等待集群工作进程返回任务结果,这是您希望在主进程上看到的结果。如果它花费大量时间进行
序列化
,这将意味着它花费大量时间将任务发送给工作人员,这将是一个不好的迹象

不幸的是,您无法判断
取消序列化
在阻塞、等待结果数据到达以及实际传输该数据上花费了多少时间。工作人员可能很容易计算出结果,而且计算量很大,或者计算时间很长,结果很小:无法从分析数据中判断

因此,要使
取消序列化
执行更快,您需要让工作人员更快地计算结果,或者如果可能的话,使结果更小。此外,使用
makeCluster
useXDR=FALSE
选项可能会有所帮助。它可以通过不使用XDR对数据进行编码来提高性能,从而使
序列化
取消序列化
更快

我认为将所有输入数据保存到
.Rdata
不会有什么帮助,因为您没有花太多时间向工作人员发送数据,这可以从
序列化
函数中花费的时间很短看出。我想那会让你慢一点


我能想到的唯一其他建议是尝试使用
parlappy
clusterApplyLB
,而不是
clusterApply
。我建议使用
parlappy
,除非您有特定的理由使用其他函数之一,因为
parlappy
通常是最有效的
clusterApplyLB
对于执行耗时较长但长度可变的任务非常有用。

好吧,它们将3*N^2数据传输给工作者(对于NxN矩阵为x,y,z值),并将2N+N^2(x,y坐标向量和z矩阵)传输回,因此可能是我计算密集型和更大的集群(每个任务更小的插值网格)会有帮助。我会测试并报告我的发现。