[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