Processamento Paralelo em Scala  XML
Índice dos Fóruns » Outras Linguagens
Autor Mensagem
Rafael Afonso
Virtual Machine Man
[Avatar]
Membro desde: 05/12/2002 16:03:43
Mensagens: 719
Localização: São Paulo/SP
Offline

Olá:

Estou experimentando usar Programação Paralela em Scala. Baseado neste exemplo do site StackOverflow, criei um programa baseado no Problema 1 do Project Euler. Experimentei três modos: O primeiro é uma execução simples, sem paralelismo. O segundo usando a API do java.util.concurrency, através de Executors e Callables. O Terceiro, baseado na sugestão da página do StackOverflow, usando scala.Futures. O objetivo é comparar os tempos de se percorrer o range paralelamente e executar a soma.
Segue-se o código:

O resultados que obtive foram os seguntes:
- max = 10:

Single : (23,31)
Pool : (23,16)
Futures: (23,31)

- max = 100:

Single : (2318,33)
Pool : (2318,31)
Futures: (2318,55)

- max = 1000:

Single : (233168,42)
Pool : (233168,111)
Futures: (233168,364)

- max = 10000:

Single : (23331668,144)
Pool : (23331668,544)
Futures: ... demorou muito e cancelei a execução

Claramente usando as APis de concorrencia do Java e de Scala não está gerando os resultados esperados. Portanto eu pergunto: Onde estou errando? Qual seria a forma mais adequada de se utilizar a Concorrência? E quanto aos atores de Scala? Como eles poderiam ser utilizados?

Grato,

Rafael Ubiratam Clemente Afonso
---------------------------------------
GitHub
ScalaFX
LinkedIn
[MSN]
mochuara
GUJ Master
[Avatar]
Membro desde: 20/05/2009 11:21:32
Mensagens: 1776
Offline

O resultado que vc esperava era qual? uma solução ser mais rápida que a outra?

Acho que vc esta confundindo programação concorrente (que é a execução por diferentes threads) com paralelismo (execução em paralelo para fins de performance).

Scala não é capaz de explorar paralelismo de threads automaticamente. Alias, não conheco nenhuma linguagem que faça isso. Geralmente essa é uma decisão que fica a critério do programador, e o papel da linguagem é fornecer uma API que seja capaz de tirar proveito desse recurso. Em clojure por exemplo, existe uma variante da função map que é capaz de explorar paralelismo, veja pmap/pcalls. Em Scala não sei como funciona, sugiro que de uma olhada na documentação da linguagem.

O motivo pela qual a solução que usa pool de threads é pouca coisa mais rapida que as demais é porque, apesar de existirem 5 threads, elas não ajudam em quase nada já que comparado aos resto da computação que é feita, executar a expressão (n % 3 == 0) || (n % 5 == 0) é praticamente irrelevante, como mostrado pelos resultados obtidos. Passe o filtro para ser executado pela thread usando pool.invokeAll ao inves de pool.submit, que provavelmente o desempenho ira melhorar.

Sobre Futures, isso não tem nada a ver com paralelismo, é apenas uma forma de programação assincrona.

Atores é um modelo para computação distrubuida, não vejo como poderia ser usada para paralelismo local.

This message was edited 1 time. Last update was at 03/02/2010 10:40:24

Rafael Afonso
Virtual Machine Man
[Avatar]
Membro desde: 05/12/2002 16:03:43
Mensagens: 719
Localização: São Paulo/SP
Offline

Olá:

Desculpe a demora, mas aí vai a minha resposta. Em primeiro lugar nunca lidei de verdade com multiprocessamento (vide a confusão que você apontou), de forma que parece ainda terei que ralar mais. Além disso ainda não consegui entender o esquema dos Actors de Scala. De qualquer forma, experimentei utilizar ExecutorSevice/Callables e também Actors conforme me foi sugerido aqui.

Os resultados, infelizmente não foram muito melhores. E Além disso, no caso de PoolJava (ExecutorSevice/Callables) o resultado tornou-se errado a partir para 10000 e 100000.

* Max = 0
Single : (0,14)
Pool : (0,169)
PoolJava: (0,2)
Actors : (0,170)

* Max = 1
Single : (0,0)
Pool : (0,0)
PoolJava: (0,0)
Actors : (0,15)

* Max = 3
Single : (0,1)
Pool : (0,19)
PoolJava: (0,4)
Actors : (0,8)

* Max = 10
Single : (23,0)
Pool : (23,6)
PoolJava: (23,16)
Actors : (23,19)

* Max = 30
Single : (195,2)
Pool : (195,11)
PoolJava: (195,10)
Actors : (195,19)

* Max = 100
Single : (2318,1)
Pool : (2318,3)
PoolJava: (2318,8)
Actors : (2318,8)

* Max = 300
Single : (20850,2)
Pool : (20850,45)
PoolJava: (20850,29)
Actors : (20850,19)

* Max = 1000
Single : (233168,8)
Pool : (233168,71)
PoolJava: (233168,98)
Actors : (233168,122)

* Max = 3000
Single : (2098500,33)
Pool : (2098500,203)
PoolJava: (2098500,147)
Actors : (2098500,216)

* Max = 10000
Single : (23331668,48)
Pool : (23331668,189)
PoolJava: (23323633,355)
Actors : (23331668,417)

* Max = 30000
Single : (209985000,62)
Pool : (209985000,170)
PoolJava: (209985000,425)
Actors : (209985000,138)

* Max = 100000
Single : (2333316668,12)
Pool : (2333316668,518)
PoolJava: (2333253053,1103)
Actors : (2333316668,315)

Pelo visto ainda há muito o que aprender nesta área.
Mas vou seguir sua sugestão e tentar com algo que exija mais mais processamento, como verificar quais números de 0 até N são primos por exemplo.

Grato,


Rafael Ubiratam Clemente Afonso
---------------------------------------
GitHub
ScalaFX
LinkedIn
[MSN]
fabiofalci
GUJ Master
[Avatar]

Membro desde: 11/04/2006 09:23:14
Mensagens: 1057
Localização: Porto Alegre - RS
Offline

Já tentou erlang?
Agora, se quiser ficar no mundo java, tem esse projeto aqui http://akkasource.org/
Ela está na minha study list faz um tempo já.
[WWW] [MSN] [ICQ]
Rafael Afonso
Virtual Machine Man
[Avatar]
Membro desde: 05/12/2002 16:03:43
Mensagens: 719
Localização: São Paulo/SP
Offline

fabiofalci wrote:Já tentou erlang?
Agora, se quiser ficar no mundo java, tem esse projeto aqui http://akkasource.org/
Ela está na minha study list faz um tempo já.

Oi! Erlang talvez para mais tarde...
Quanto ao Akka já visto referências a ele em alguns feeds sobre Scala mas nunca prestei muita atenção. Agora vou ler o artigo sobre Actors na Wikipedia e também dois artigos do Martin Odersky (criador do Scala para quem não sabe) a respeito do assunto (aqui e aqui).

Grato,

Rafael Ubiratam Clemente Afonso
---------------------------------------
GitHub
ScalaFX
LinkedIn
[MSN]
mochuara
GUJ Master
[Avatar]
Membro desde: 20/05/2009 11:21:32
Mensagens: 1776
Offline

Rafael Afonso wrote:Olá:

Desculpe a demora, mas aí vai a minha resposta. Em primeiro lugar nunca lidei de verdade com multiprocessamento (vide a confusão que você apontou), de forma que parece ainda terei que ralar mais. Além disso ainda não consegui entender o esquema dos Actors de Scala. De qualquer forma, experimentei utilizar ExecutorSevice/Callables e também Actors conforme me foi sugerido aqui.

Os resultados, infelizmente não foram muito melhores. E Além disso, no caso de PoolJava (ExecutorSevice/Callables) o resultado tornou-se errado a partir para 10000 e 100000.

* Max = 0
Single : (0,14)
Pool : (0,169)
PoolJava: (0,2)
Actors : (0,170)

* Max = 1
Single : (0,0)
Pool : (0,0)
PoolJava: (0,0)
Actors : (0,15)

* Max = 3
Single : (0,1)
Pool : (0,19)
PoolJava: (0,4)
Actors : (0,8)

* Max = 10
Single : (23,0)
Pool : (23,6)
PoolJava: (23,16)
Actors : (23,19)

* Max = 30
Single : (195,2)
Pool : (195,11)
PoolJava: (195,10)
Actors : (195,19)

* Max = 100
Single : (2318,1)
Pool : (2318,3)
PoolJava: (2318,8)
Actors : (2318,8)

* Max = 300
Single : (20850,2)
Pool : (20850,45)
PoolJava: (20850,29)
Actors : (20850,19)

* Max = 1000
Single : (233168,8)
Pool : (233168,71)
PoolJava: (233168,98)
Actors : (233168,122)

* Max = 3000
Single : (2098500,33)
Pool : (2098500,203)
PoolJava: (2098500,147)
Actors : (2098500,216)

* Max = 10000
Single : (23331668,48)
Pool : (23331668,189)
PoolJava: (23323633,355)
Actors : (23331668,417)

* Max = 30000
Single : (209985000,62)
Pool : (209985000,170)
PoolJava: (209985000,425)
Actors : (209985000,138)

* Max = 100000
Single : (2333316668,12)
Pool : (2333316668,518)
PoolJava: (2333253053,1103)
Actors : (2333316668,315)

Pelo visto ainda há muito o que aprender nesta área.
Mas vou seguir sua sugestão e tentar com algo que exija mais mais processamento, como verificar quais números de 0 até N são primos por exemplo.

Grato,



Voce já falou em multiprocessamento, paralelismo, pool de threads, processamento distribuído alá actors... e eu continuo sem entender que resultados espera conseguir.

Não tem nada de pouco processamento no seu exemplo, como pode ser visto pelos resultados exibidos, vc é que esta distribuindo a carga de maneira errada como falei no primeiro post.
mochuara
GUJ Master
[Avatar]
Membro desde: 20/05/2009 11:21:32
Mensagens: 1776
Offline

Problema 1 do projeto euler em clojure:



Em scala:

Rafael Afonso
Virtual Machine Man
[Avatar]
Membro desde: 05/12/2002 16:03:43
Mensagens: 719
Localização: São Paulo/SP
Offline

mochuara wrote:
Voce já falou em multiprocessamento, paralelismo, pool de threads, processamento distribuído alá actors... e eu continuo sem entender que resultados espera conseguir.

Não tem nada de pouco processamento no seu exemplo, como pode ser visto pelos resultados exibidos, vc é que esta distribuindo a carga de maneira errada como falei no primeiro post.

Me desculpe se não estou sendo claro, vou dar um exemplo do que eu pretendo:
Digamos que estou numa sequencia e no momento estou em 1013 (que é primo). Enquanto rodo a verificação de sua "primalidade", poderia paralelamente verificar 1014 (divisivel por 2)*, 1015 (por 5), 1016 (por 2) e 1017 (por 3), cuja verificação é mais rápida, pois seus divisores são pequenos. Ou seja enquanto um thread faz uma verificação mais demorada, outra pode fazer uma verificação mais rápida e passar para o próximo número disponível. E quando a primeira thread terminar sua verificação tamém pegaria o próximo número da fila.

* Claro que um algorítmo de verdade pularia os números pares, estou apenas dando um exemplo.

Grato,

Rafael Ubiratam Clemente Afonso
---------------------------------------
GitHub
ScalaFX
LinkedIn
[MSN]
mochuara
GUJ Master
[Avatar]
Membro desde: 20/05/2009 11:21:32
Mensagens: 1776
Offline

Parece que esse tipo de problema não é um bom candidato para processamento paralelo:

http://groups.google.com/group/clojure/msg/47030e46692dcffd
 
Índice dos Fóruns » Outras Linguagens
Ir para:   
Powered by JForum 2.1.8 © JForum Team