Como posso saber se estou usando demais o multi-threading?

15

Atualmente, sinto que estou usando o multi-threading.

Eu tenho 3 tipos de dados, A, B e C.

Cada um Apode ser convertido em vários se Bcada um Bpode ser convertido em vários Cs.

Eu só estou interessado em tratar Cs.

Eu poderia escrever isso facilmente com algumas funções de conversão. Mas eu me peguei implementando-o com threads, três filas ( queue_a, queue_be queue_c). Existem dois threads fazendo as diferentes conversões e um trabalhador:

  • ConverterAqueue_ae escreve paraqueue_b
  • ConverterBqueue_be escreve paraqueue_c
  • Worker lida com cada elemento de queue_c

As conversões são bastante mundanas, e não sei se esse modelo é muito complicado. Mas parece extremamente robusto para mim. Cada "conversor" pode começar a funcionar mesmo antes da chegada dos dados nas filas e, a qualquer momento no código, posso apenas "enviar" novos As ou Bse acionará o pipeline de conversão que, por sua vez, acionará um trabalho do trabalhador fio.

Até o código resultante parece mais simples. Mas ainda não tenho certeza se estou abusando de tópicos por algo simples.

exuma
fonte
5
Penso que esta questão precisa ser encurtada um pouco para ser seguida. O título também é enganador - parece que você está prestes a lançar um discurso retórico (mesmo que não esteja). Talvez você deva perguntar algo mais próximo de "Como posso saber se estou usando demais o multithreading?"
KChaloux #
@KChaloux Eu concordo. Eu editei e espero que capte meus pensamentos um pouco melhor.
Exhuma
4
@exhuma Awesome. Seu -1 torna-se +1
KChaloux
3
@KChaloux ... a diferença de uma visita ao banheiro pode fazer para o seu processo de pensamento ... :)
exhuma
Este livro em PDF online, Mature Optimization Handbook (publicado há alguns dias) fala sobre efeitos sistemáticos nos quais o impacto de um módulo no desempenho geral do sistema às vezes pode exceder a fração do tempo de execução do módulo.
rwong

Respostas:

16

É quase sempre mais simples pensar sequencialmente e depois modificar essa lógica para funcionar melhor usando threads. E, como diz a expressão: "Se não estiver quebrado, não conserte". A maioria dos programadores não usa threads simplesmente porque não há necessidade de usá-los.

Se você se sentir mais confortável usando-os, mais poder para você. No entanto, saiba que, se os threads não oferecem um aumento de velocidade ao eliminar gargalos, eles certamente estão diminuindo a velocidade do seu programa.

Considere também que os sistemas que dedicam apenas uma CPU a um processo simularão vários threads por um único thread, a fim de economizar recursos (isso não ocorre frequentemente em computadores modernos, embora os aplicativos de smartphones ainda estejam muito sujeitos a esse abuso). Nesse caso, mesmo se você estiver eliminando gargalos com o uso de threads, será realmente mais lento do que se você não usasse threads.

E, talvez o motivo mais sutil de cautela ao usar threads, mas certamente não seja o menos importante, os threads tendem a fazer o que você não espera. Sim, se você estiver tomando precauções, deve ficar bem. Sim, se seus threads não gravarem em variáveis ​​compartilhadas entre threads, você deve ficar bem. Dito isto, é muito difícil encontrar erros relacionados a threads. Como sou da idéia de que um programador nunca pode eliminar completamente a possibilidade de criar bugs no código e, portanto, um programador deve tomar medidas para se proteger contra possíveis bugs, em vez de se concentrar em eliminá-los completamente, você deve definitivamente aplicar essa ideia ao hard- para encontrar erros de thread também. Em outras palavras, saiba que, apesar dos seus melhores esforços,

Então você deve usar threads de qualquer maneira? Bem, um conhecimento saudável dos threads certamente não é uma coisa ruim, especialmente se você se tornar bom nisso. No entanto, o movimento dos últimos tempos tem sido em direção a linguagens de thread único, como o node.js. Uma das principais vantagens de ter um único encadeamento é que é fácil escalar e certas otimizações podem ser feitas se você souber que as instruções devem ser executadas seqüencialmente (mesmo que otimizações possam significar que instruções que podem ser executadas em paralelo podem ser executado de forma assíncrona).

Dito isto, eu digo: faça o que for mais confortável para você. Na minha experiência, escrever um programa que você entende tem maior prioridade do que fazê-lo funcionar mais rapidamente. Apenas certifique-se de usar threads quando achar que isso ajuda a escrever o programa, e não porque você deseja que ele funcione mais rapidamente, pois você não deve se preocupar tanto com o desempenho como está escrevendo o programa (a otimização é importante, mas também pode esperar).

Neil
fonte
Você está fazendo pontos interessantes. No meu caso, o pipeline de conversão não é sobre desempenho. É sobre simplicidade / legibilidade do código. O segmento de trabalho é sobre desempenho. Cada tarefa final é executada em uma máquina remota e o envio de vários trabalhos faz com que seja executado significativamente mais rápido.
Exhuma
2
@exhuma Além da execução paralela por meio de vários threads, você também pode usar técnicas assíncronas como Futures / Promises ou um estilo orientado a retorno de chamada. Observe que você pode modelar pipelines encadeando iteradores / fluxos; não há necessidade de realmente usar tópicos - exceto se você quiser utilizar múltiplas CPUs (No código de rede, este quase nunca é o caso)
amon
@exhuma Sim, os tópicos ajudam no desempenho em geral. Meu argumento era que, se você não está fazendo isso porque é muito lento, deve fazê-lo porque ajuda a escrever seu programa. A otimização deve sempre vir mais tarde. Pode até ser que a remoção de threads do seu programa esteja otimizando (embora esse não seja o caso da maioria dos programadores).
911 Neil
OT: Eu amo o seu avatar. Me faz sorrir.
Marjan Venema
@exhuma, eu concordo com esta resposta, mas gostaria de acrescentar que, se você for usar threads para simplificar o código, tudo bem, mas tenha muito cuidado para entender a segurança da thread e possíveis dicas com vários threads. O que pode parecer um simples pedaço de código multithread pode facilmente ter condições de corrida ocultas que podem levar a uma variedade de bugs muito difíceis de rastrear.
Ben Lee