Медленнее ddply, когда .parallel = TRUE в Mac OS X версии 10.6.7 - PullRequest
6 голосов
/ 24 августа 2011

Я пытаюсь заставить 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 

Почему dpply медленнее, когда я запускаю .parallel = TRUE?Я искал онлайн безрезультатно.Я также пробовал registerDoMC() и результаты были такими же.

Ответы [ 2 ]

11 голосов
/ 24 августа 2011

Данные 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.

9 голосов
/ 24 августа 2011

Параллельная работа будет медленнее, чем последовательная, когда затраты на связь между узлами превышают время расчета функции. Другими словами, для отправки данных в / из узлов требуется больше времени, чем для вычисления.

Для того же набора данных затраты на связь приблизительно фиксированы, поэтому параллельная обработка будет более полезной по мере увеличения времени, затрачиваемого на оценку функции.

UPDATE:
Приведенный ниже код показывает, что 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
...