mclapply () работает значительно хуже, чем lapply ().Как я могу ускорить процесс? - PullRequest
0 голосов
/ 12 февраля 2019

Я новичок в параллельных вычислениях в R и хочу использовать параллельный пакет для ускорения моих вычислений (что более сложно, чем в приведенном ниже примере).Однако при использовании функции mclapply вычисления занимают больше времени по сравнению с обычной функцией lapply.

Я установил на свой ноутбук новую версию Ubuntu 18.04.2 LTS с 7,7 ГБ памяти и процессором Intel® Core ™ i7-4500U @ 1,80 ГГц × 4.Я бегу R на R студии.

require(parallel)

a <- seq(0, 1, length.out = 110) #data
b <-  seq(0, 1, length.out = 110)
c <- replicate(1000, sample(1:100,size=10), simplify=FALSE)

function_A <- function(i, j, k) { # some random function to examplify the problem
  i+ j * pmax(i-k,0) 
}

#running it with mclapply 
ptm_mc <- proc.time()  
output <- mclapply(1:NROW(c), function(o){ 
  mclapply(1:NROW(a),function(p) function_A(a[p], b, c[[o]]))})
time_mclapply <- proc.time() - ptm_mc

# running it with lapply
ptm_lapply <- proc.time()  
output <- lapply(1:NROW(c), function(o){
  lapply(1:NROW(a),function(p) function_A(a[p], b, c[[o]]))})
time_lapply <- proc.time() - ptm_lapply

Результаты от lapply намного быстрее, чем результаты mclapply:

 > time_mclapply
       user      system     elapsed 
      6.030     439.112     148.088 
 > time_lapply
       user      system     elapsed 
      1.662       0.165       1.827 

Почему я получаю этот результат?Это из-за моей настройки или из-за общей проблемы?Как я могу получить результаты, которые на самом деле быстрее, чем приятные результаты, так что все будет быстрее?

ОБНОВЛЕНИЕ: Обновление двух оставшихся комбинаций вложенных циклов:

ptm_mc_OUT <- proc.time()  
output <- mclapply(1:NROW(c), function(o){
  lapply(1:NROW(a),function(p) function_A(a[p], b, c[[o]]))})
 time_mclapply_OUT <- proc.time() - ptm_mc_OUT

ptm_mc_IN <- proc.time()  
output <- lapply(1:NROW(c), function(o){
  mclapply(1:NROW(a),function(p) function_A(a[p], b, c[[o]]))})
time_mclapply_IN <- proc.time() - ptm_mc_IN

 require(dplyr)
times <- rbind(time_mclapply,
                      time_lapply,
                      time_mclapply_OUT, 
                      time_mclapply_IN) %>% data.frame()

times

Это дает нам

>times
                  user.self sys.self elapsed user.child sys.child
time_mclapply         0.075    0.081  22.621      1.933    34.266
time_lapply           1.070    0.049   1.118      0.000     0.000
time_mclapply_OUT     0.064    0.077   0.884      2.539    34.587
time_mclapply_IN      1.329   31.843  37.426      5.108    28.879

и при следующем запуске я получил (так что запуститьвремена, кажется, меняются совсем немного, есть ли лучший способ их отображения?)

times_lapply
                   user.self sys.self elapsed user.child sys.child
time_mclapply         0.324    0.121   9.108      0.000     0.000
time_lapply           1.060    0.049   1.108      0.000     0.000
time_mclapply_OUT     0.211    0.092   1.155     10.791    19.632
time_mclapply_IN      1.221   22.196  27.089      5.130    23.032

1 Ответ

0 голосов
/ 12 февраля 2019

Пусть N будет числом потоков вашей машины.Некоторые рекомендации:

  1. Не следует использовать два уровня параллелизма, поскольку вы будете использовать N ^ 2 потоков.

  2. Вы должны попытаться распараллелить ввнешний цикл вместо внутреннего (поскольку издержки параллелизма произойдут только один раз).

  3. Вы не должны использовать все потоки (люди обычно используют N-1 или N / 2).

При использовании N / 2 (mc.cores = parallel::detectCores() / 2) time_mclapply_OUT в два раза быстрее, чем time_lapply.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...