Por que meu solucionador paralelo é mais lento que meu solucionador sequencial?

14

Eu estava brincando com o PETSc e percebi que quando executo meu programa com mais de um processo via MPI, ele parece correr ainda mais devagar ! Como posso verificar para ver o que está acontecendo?

Sean Farley
fonte
Não postar isso como resposta, porque é realmente um "o quê", e não um "como", mas tive problemas semelhantes no passado que foram causados ​​por uma seção de código protegida por mutex sendo acessada a partir de vários threads. Às vezes, você precisa verificar o bloqueio de recursos compartilhados nos bastidores.
David Z

Respostas:

13

Isso pode surgir de fatores arquitetônicos :

Se a mesma largura de banda de memória estiver disponível para um ou mais processos, quase não haverá aceleração, pois o SpMV e as operações de álgebra linear relacionadas são limitadas pela largura de banda da memória.

Também pode ser que a sobrecarga de comunicação sobrecarregue a computação local. Por exemplo, nos métodos iterativos lineares, recomendamos ter pelo menos 10.000 incógnitas por processo.

ou fatores numéricos :

Os pré-condicionantes paralelos costumam ser mais fracos que seus equivalentes seriais. Por exemplo, o bloco Jacobi fica mais fraco quanto mais blocos você usar. Portanto, você precisa levar em consideração o tempo extra gasto em iterações lineares extras. As condições não lineares em geral não funcionam dessa maneira, portanto as iterações de Newton geralmente são constantes.

Matt Knepley
fonte
8

Sempre que tentar paralelizar um programa, você precisará equilibrar vários custos, mas principalmente há

  • O custo de executar cada cálculo
  • O custo de qualquer comunicação entre esses cálculos
  • O custo de gerenciar esses cálculos

Se seus cálculos forem embaraçosamente paralelos , o custo das comunicações será muito baixo (apenas entrada e saída) e o custo do gerenciamento deverá ser muito baixo.

Se você tiver interdependências entre cálculos, o custo das comunicações pode aumentar significativamente. Se você tiver um algoritmo complexo que leva um tempo diferente para concluir em qualquer cálculo, a complexidade do gerenciamento aumenta, à medida que você tenta usar eficientemente os recursos que possui.

Como em qualquer forma de otimização, a chave é fazer benchmark. Veja como ele funciona sem o MPI, como ele funciona com o MPI e um processo e, em seguida, como ele é escalado.

Se você estiver jogando com o CUDA, tente fornecer muito mais dados. Um teste aqui resultou em uma aceleração negativa. Fornecemos 1000 vezes mais dados e a versão GP-GPU terminou quase ao mesmo tempo, enquanto a versão em execução na CPU principal demorou 1000 vezes.

Mark Booth
fonte
3

Eu recomendo que você faça o seguinte:

  • Faça um perfil do tempo de execução do seu código, com e sem paralelismo. Se você tiver dúvidas sobre como fazer isso, podemos ajudá-lo se você descrever melhor seu código.

  • Agora você pode se concentrar nas peças que ficam mais lentas em paralelo. Você deve estar ciente de que a comunicação entre processos pode ser lenta. Como Mark e Sean apontaram, apenas porque um problema pode ser dividido em threads não significa que isso será eficiente. Você tem que olhar mais profundamente. Mas se você criar um perfil do seu código, poderá ajudar a encontrar erros existentes. Meus dois centavos.

Se você explicar o que está fazendo com mais detalhes, por exemplo, com um fluxo de trabalho, alguém poderá dar uma explicação melhor.

jbcolmenares
fonte
@ Sketch: você está certo. Desculpe e obrigado por perceber. Editou o texto.
jbcolmenares