【问题标题】:Slower ddply when .parallel=TRUE on Mac OS X Version 10.6.7在 Mac OS X 版本 10.6.7 上 .parallel=TRUE 时 ddply 变慢
【发布时间】:2025-11-29 08:40:01
【问题描述】:

我正在尝试让 ddply 在我的 Mac 上并行运行。我使用的代码如下:

library(doMC)
library(ggplot2) # for the purposes of getting the baseball data.frame
registerDoMC(2)


> system.time(ddply(baseball, .(year), numcolwise(mean)))
   user  system elapsed 
  0.959   0.106   1.522 
> system.time(ddply(baseball, .(year), numcolwise(mean), .parallel=TRUE))
   user  system elapsed 
  2.221   2.790   2.552 

为什么当我运行 .parallel=TRUE 时 ddply 会变慢?我在网上搜索无济于事。我也试过registerDoMC(),结果是一样的。

【问题讨论】:

标签: macos r parallel-processing plyr


【解决方案1】:

baseball 数据可能太小,无法通过并行计算看到改进;通过并行计算,将数据传递给不同进程的开销可能会淹没任何加速。使用rbenchmark 包:

baseball10 <- baseball[rep(seq(length=nrow(baseball)), 10),]

benchmark(noparallel = ddply(baseball, .(year), numcolwise(mean)),
    parallel = ddply(baseball, .(year), numcolwise(mean), .parallel=TRUE),
    noparallel10 = ddply(baseball10, .(year), numcolwise(mean)),
    parallel10 = ddply(baseball10, .(year), numcolwise(mean), .parallel=TRUE),
    replications = 10)

给出结果

          test replications elapsed relative user.self sys.self user.child sys.child
1   noparallel           10   4.562 1.000000     4.145    0.408      0.000     0.000
3 noparallel10           10  14.134 3.098203     9.815    4.242      0.000     0.000
2     parallel           10  11.927 2.614423     2.394    1.107      4.836     6.891
4   parallel10           10  18.406 4.034634     4.045    2.580     10.210     9.769

使用 10 倍大的数据集,并行的惩罚更小。更复杂的计算也会使它更加有利于并行,可能会给它带来优势。

这是在 Mac OS X 10.5.8 Core 2 Duo 机器上运行的。

【讨论】:

    【解决方案2】:

    当节点之间的通信成本大于函数的计算时间时,并行运行会比顺序运行慢。换句话说,向/从节点发送数据比执行计算花费的时间更长。

    对于相同的数据集,通信成本几乎是固定的,因此随着评估函数所花费的时间增加,并行处理将变得更加有用。

    更新:
    下面的代码显示 0.14 秒(在我的机器上)用于评估 .fun。这意味着通信必须少于 0.07 秒,这对于 baseball 大小的数据集是不现实的。

    Rprof()
    system.time(ddply(baseball, .(year), numcolwise(mean)))
    #    user  system elapsed 
    #    0.28    0.02    0.30
    Rprof(NULL)
    summaryRprof()$by.self
    #               self.time self.pct total.time total.pct
    # [.data.frame       0.04    12.50       0.10     31.25
    # unlist             0.04    12.50       0.10     31.25
    # match              0.04    12.50       0.04     12.50
    # .fun               0.02     6.25       0.14     43.75
    # structure          0.02     6.25       0.12     37.50
    # [[                 0.02     6.25       0.08     25.00
    # FUN                0.02     6.25       0.06     18.75
    # rbind.fill         0.02     6.25       0.06     18.75
    # anyDuplicated      0.02     6.25       0.02      6.25
    # gc                 0.02     6.25       0.02      6.25
    # is.array           0.02     6.25       0.02      6.25
    # list               0.02     6.25       0.02      6.25
    # mean.default       0.02     6.25       0.02      6.25
    

    这是与雪的平行版本:

    library(doSNOW)
    cl <- makeSOCKcluster(2)
    registerDoSNOW(cl)
    
    Rprof()
    system.time(ddply(baseball, .(year), numcolwise(mean), .parallel=TRUE))
    #    user  system elapsed 
    #    0.46    0.01    0.73
    Rprof(NULL)
    summaryRprof()$by.self
    #                     self.time self.pct total.time total.pct
    # .Call                    0.24    33.33       0.24     33.33
    # socketSelect             0.16    22.22       0.16     22.22
    # lazyLoadDBfetch          0.08    11.11       0.08     11.11
    # accumulate.iforeach      0.04     5.56       0.06      8.33
    # rbind.fill               0.04     5.56       0.06      8.33
    # structure                0.04     5.56       0.04      5.56
    # <Anonymous>              0.02     2.78       0.54     75.00
    # lapply                   0.02     2.78       0.04      5.56
    # constantFoldEnv          0.02     2.78       0.02      2.78
    # gc                       0.02     2.78       0.02      2.78
    # stopifnot                0.02     2.78       0.02      2.78
    # summary.connection       0.02     2.78       0.02      2.78
    

    【讨论】:

    • 是的,我们在集群上运行时遇到了这个问题。我怎样才能确定这就是这里发生的事情?
    • 我不知道它是否确定性,但我在编辑中提供了一些证据。