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

FHRB Toledo fernandohtoledo em gmail.com
Terça Novembro 27 11:10:49 BRST 2012


Adriano,

Veja que com certeza a vantagem do mclapply vai depender de como você
engendrou sua paralelização, explico: a vantagem não é efetiva pois existe
um tempo que o processador vai demorar " distribuindo" as tarefas entre
processadores! Você deve observar isso!

Vou citar um caso.

Imagine ter que realizar 1000 simulações em 10 cenários (entenda cenários
como uma alteração dos parâmetros da simulação) e seja uma máquina com 5
processadores. Nesse caso, posso pensar em realizar uma paralelização de
duas formas (deve haver mais, mas isso não evm ao caso). Uma delas seria,
colocar um laço (for, por exemplo), entre os cenários e distribuir as 1000
simulações entre os 4 processadores e cada um faria 200 destas. Ou então,
distribuir os cenários entre os 5 processadores, o que ele faria em duas
vezes e então usar um laço para cada uma das 1000 simulações.

Como você pode observar no primeiro caso estão envolvidos MUITO mais
distribuições de códigos entre processadores que no primeiro, portanto,
para a mesma tarefa, com os mesmos recursos computacionais teremos tempos
bastante distintos. Essa distinção de tempo também leva em conta o próprio
tempo da tarefa, se por acaso cada simulação leva um tempo "pequeno" acho
(O Benilton pode confirmar ou descordar :) ), a segunda opção seria bem
mais vantajosa, mas se cada simulação demorar "bastante" os tempos tendem a
acabar se compensando!

Espero ter sido claro! Fico à disposição (parafraseando o Walmes).

att,
FH

2012/11/27 Adriano S. Melo <asm.adrimelo em gmail.com>

> 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
> _______________________________________________
> R-br mailing list
> R-br em listas.c3sl.ufpr.br
> https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br
> Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça
> código mínimo reproduzível.
>
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://listas.inf.ufpr.br/pipermail/r-br/attachments/20121127/1327bab7/attachment.html>


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