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

Adriano S. Melo asm.adrimelo em gmail.com
Terça Novembro 27 10:51:45 BRST 2012


Colegas,
Enviei o e-mail abaixo mas não recebi resposta. Desconfio que tenha
sido devido ao tamanho da mensagem. Segue uma versão resumida do
problema. Uso Ubuntu 12.04.

Aparentemente, o maclapply (pacotes multicore ou parallel) tem
desempenho distinto dependendo do código:

## Aqui o mclapply foi mais bem mais lento que um for loop:
 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


### 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

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

Abraços e grato por qualquer ajuda,
Adriano
Ecologia - UFG


Em 25 de novembro de 2012 18:21, Adriano S. Melo
<asm.adrimelo em gmail.com> escreveu:
> 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