[R-br] Lentidão do mclapply() em alguns casos, mas não em outros

Adriano S. Melo asm.adrimelo em gmail.com
Domingo Novembro 25 18:21:31 BRST 2012


Colegas,
Estou com um problema de lentidão no uso do mclapply do pacote
multicore. Uso Ubuntu 12.04 em Dell Latitude E6500, 4Gb Ram e
processador Centrino2. Trabalho com R no gedit (repeti algumas coisas
diretamente no R executado no terminal mas não mudou nada). Já
brinquei bastante com o comando, mas ainda não consegui entender
exatamente o que está acontecendo (veja que fiz vários testes abaixo).

Seguindo uma mensagem anterior desta lista (18out12), executei o
codigo do Fernando H. Toledo em:
http://ridiculas.wordpress.com/2011/10/23/paralelizacao-de-processos/
O tempo de processammento SEM mcapply foi de:
1> tempoA[3]
elapsed
  2.065

Com o mcapply foi de:
1> tempoB[3]
elapsed
  2.135

Visto que o tempo do mclapply foi até maior, tentei descobrir o que
estava acontecendo.
Achei isto (https://github.com/markmfredrickson/RItools/issues/2):
"My understanding is that multicore first checks to see if the
mc.cores argument is set. If so, it uses that value. Next, it checks
options("cores"), if this is set, it will use that value. If neither
condition is true, it runs detectCores() itself. So in general, we do
not need to manually detect cores. The multicore help page has more
details on this.

If you want to override in RItools, you have two options. 1)
options("cores" = 2)  -- multicore will respect this. 2)
options("RItools-apply" = function(lst, f) { mclapply(lst, f,
mc.cores= 2) }). You can also use the second strategy to set other
mclapply options.

No meu computador:
getOption("cores")
NULL

Usei a sugestão 1) acima:
options("cores" = 2)
getOption("cores")
[1] 2

Executei o código novamente, mas não adiantou:
1> tempoA[3]
elapsed
  2.197
1> tempoB[3]
elapsed
  2.302


Usei a sugestão 2) acima, mas também não adiantou:
1> tempoA[3]
elapsed
  2.172
1> tempoB[3]
elapsed
  2.249

Fechei tudo e repeti os comandos usando o mclapply do pacote parallel.
Ele não reconheceu o número de CPUs e portanto coloquei como
argumento: mc.cores = 2
Melhorou apenas um pouquinho:
1> tempoA[3]
elapsed
   2.22
1> tempoB[3]
elapsed
  2.205

===>> Continuei brincando com o mclapply e vi que as coisas podem ser
diferentes:
system.time({
 a<-mclapply(1:1000, function(numero) sd(rnorm(100000)))
})
  usuário   sistema decorrido
  528.277     4.544    92.195

system.time({
a<-vector('list', 1000)
for (i in 1:1000){a[[i]]<-sd(rnorm(100000))}
})
  usuário   sistema decorrido
   16.301     0.520    16.835
#### Notem que aqui o mclapply foi BEM lento.


#### Mas neste exemplo abaixo ele reduziu o tempo pela metade (como
esperado, visto que tenho 2 CPUs):
library(vegan)
data(BCI)
system.time({
a<-mclapply(1:100,   function(numero) nestednodf(BCI))
})
 usuário   sistema decorrido
  127.996     2.520    47.902


system.time({
a<-vector('list', 100)
for (i in 1:100){a[[i]]<-nestednodf(BCI)}
})
  usuário   sistema decorrido
   82.765     0.352    83.204
####


Eu tenho 2 CPUs:
1> detectCores() # função do pacote parallel
[1] 2
No Monitor do Sistema pude observar que de fato o mclapply está usando
as duas CPUs para processamento (tanto com multicore quanto com
parallel).

Sugestões do que pode estar acontecendo?
Em que situação vale a pena usar o mclapply?

Abraços,
Adriano S. Melo
Ecologia - UFG


Mais detalhes sobre a lista de discussão R-br