3 回答
TA贡献2065条经验 获得超14个赞
并行运行工作会产生开销。只有当您在工作节点上触发的作业花费大量时间时,并行化才能提高整体性能。当单个作业只需几毫秒时,不断解雇作业的开销将降低整体性能。诀窍是在节点上划分工作,使作业足够长,比如说至少几秒钟。我使用它可以同时运行六个Fortran模型,但是这些单独的模型运行需要几个小时,几乎可以消除开销的影响。
请注意,我没有运行您的示例,但是当parallization比顺序运行花费更长时间时,我上面描述的情况通常是个问题。
TA贡献1890条经验 获得超9个赞
这些差异可归因于1)通信开销(特别是如果跨节点运行)和2)性能开销(例如,与启动并行化相比,您的工作不是那么密集)。通常,如果您正在并行化的任务并不那么耗时,那么您将发现并行化并没有太大的影响(这在大型数据集中非常明显。
即使这可能不能直接回答您的基准测试,但我希望这应该是相当简单的并且可以与之相关。作为一个例子,在这里,我建立一个data.frame与1e6具有行1e4唯一的列group项,并在列中的某些值val。然后我plyr在parallel使用doMC和不使用并行化时运行。
df <- data.frame(group = as.factor(sample(1:1e4, 1e6, replace = T)),
val = sample(1:10, 1e6, replace = T))
> head(df)
group val
# 1 8498 8
# 2 5253 6
# 3 1495 1
# 4 7362 9
# 5 2344 6
# 6 5602 9
> dim(df)
# [1] 1000000 2
require(plyr)
require(doMC)
registerDoMC(20) # 20 processors
# parallelisation using doMC + plyr
P.PLYR <- function() {
o1 <- ddply(df, .(group), function(x) sum(x$val), .parallel = TRUE)
}
# no parallelisation
PLYR <- function() {
o2 <- ddply(df, .(group), function(x) sum(x$val), .parallel = FALSE)
}
require(rbenchmark)
benchmark(P.PLYR(), PLYR(), replications = 2, order = "elapsed")
test replications elapsed relative user.self sys.self user.child sys.child
2 PLYR() 2 8.925 1.000 8.865 0.068 0.000 0.000
1 P.PLYR() 2 30.637 3.433 15.841 13.945 8.944 38.858
正如您所看到的,并行版本的plyr运行速度慢了3.5倍
现在,让我使用相同的data.frame,但不是计算sum,让我构建一个更苛刻的功能,比如说median(.) * median(rnorm(1e4)((无意义,是的):
你会看到潮汐开始转变:
# parallelisation using doMC + plyr
P.PLYR <- function() {
o1 <- ddply(df, .(group), function(x)
median(x$val) * median(rnorm(1e4)), .parallel = TRUE)
}
# no parallelisation
PLYR <- function() {
o2 <- ddply(df, .(group), function(x)
median(x$val) * median(rnorm(1e4)), .parallel = FALSE)
}
> benchmark(P.PLYR(), PLYR(), replications = 2, order = "elapsed")
test replications elapsed relative user.self sys.self user.child sys.child
1 P.PLYR() 2 41.911 1.000 15.265 15.369 141.585 34.254
2 PLYR() 2 73.417 1.752 73.372 0.052 0.000 0.000
这里,并行版本比非并行版本1.752 times 更快。
编辑:关注 @Paul的评论,我刚刚实施了一个小延迟Sys.sleep()。当然结果很明显。但仅仅为了完整起见,这是20 * 2 data.frame的结果:
df <- data.frame(group=sample(letters[1:5], 20, replace=T), val=sample(20))
# parallelisation using doMC + plyr
P.PLYR <- function() {
o1 <- ddply(df, .(group), function(x) {
Sys.sleep(2)
median(x$val)
}, .parallel = TRUE)
}
# no parallelisation
PLYR <- function() {
o2 <- ddply(df, .(group), function(x) {
Sys.sleep(2)
median(x$val)
}, .parallel = FALSE)
}
> benchmark(P.PLYR(), PLYR(), replications = 2, order = "elapsed")
# test replications elapsed relative user.self sys.self user.child sys.child
# 1 P.PLYR() 2 4.116 1.000 0.056 0.056 0.024 0.04
# 2 PLYR() 2 20.050 4.871 0.028 0.000 0.000 0.00
这里的差异并不令人惊讶。
- 3 回答
- 0 关注
- 775 浏览
添加回答
举报