8

我是集群处理的新手,可以就如何更好地准备数据和/或从parallel包中调用函数提出一些建议。我已经阅读了parallels包装小插曲,所以对发生了什么有一个模糊的了解。

我要并行化的函数调用 2-D interpolation tool akima::interp。我的输入由 3 个矩阵(或向量 - 在 中都相同R)组成:一个包含 x 坐标,一个包含 y 坐标,一个包含“z”或数据值,用于一组样本点。 interp使用它在常规网格上生成插值数据,以便我可以绘制字段。一旦我设置了这 3 个项目,我将它们切成“块”并喂它们以逐块clusterApply执行。interp

我正在使用 Windows7、i7 CPU(8 核)机器。这是Rprof具有 1e6 个点(如果您愿意,可以为 1000x1000)的输入数据集的摘要输出,并映射到 1000x1000 输出网格。

所以我的问题是:1)“反序列化”似乎花费了大部分时间。这是什么操作,如何减少?2)一般来说,由于每个工作人员加载默认.Rdata文件,如果我首先将所有输入数据保存到.Rdata不需要传递给工作人员,是否会提高速度?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
4

1 回答 1

9

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

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

不幸的是,您无法确定unserialize阻塞、等待结果数据到达所花费的时间,以及实际传输该数据所花费的时间。结果可能很容易被工作人员计算出来并且非常庞大,或者它们可能需要很长时间才能计算并且很小:无法从分析数据中分辨出来。

因此,为了unserialize加快执行速度,如果可能的话,您需要让工作人员更快地计算他们的结果,或者使结果更小。此外,使用该makeCluster useXDR=FALSE选项可能会有所帮助。它可能会通过不使用 XDR 对您的数据进行编码来提高您的性能,从而使两者都变得serialize更快unserialize

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

我能想到的唯一其他建议是尝试使用parLapplyor clusterApplyLB,而不是clusterApply。我建议使用parLapply,除非您有特定理由使用其他功能之一,因为parLapply通常是最有效的。 clusterApplyLB当您的任务需要很长但可变的时间来执行时,它很有用。

于 2013-10-15T14:13:24.030 回答