Questão Número ideal de threads enquanto multitarefa


Eu sei que perguntas semelhantes foram feitas, mas acho que meu caso é um pouco diferente.

Digamos que eu tenha um computador com 8 núcleos e memória infinita com um sistema operacional Linux.

Eu tenho um software de cálculo chamado Gaussian que pode aproveitar o multithreading. Então eu configurei sua contagem de threads para 8 para um único cálculo para a velocidade máxima. No entanto, eu realmente não consigo decidir o que fazer quando preciso executar, por exemplo, 8 cálculos simultaneamente. Nesse caso, devo definir a contagem de threads como 1 (total de 8 threads gerados em 8 processos) ou mantê-lo 8 (total de 64 threads gerados em 8 processos) para cada trabalho? Isso realmente importa muito? Uma pergunta relacionada é que o sistema operacional faz automaticamente o core-parking para diferentes núcleos para cada thread?

EDITAR: Eu sei que o benchmarking é a melhor maneira de saber. A coisa é, os computadores pertencem à minha universidade, então eles estão ocupados o tempo todo. Em outras palavras, sua carga de trabalho varia de maneira incontrolável para mim, porque outras pessoas também estão usando esses computadores para seus cálculos, impossibilitando a experimentação. Além disso, o software é muito caro (1500 $ ou algo assim) e licenciado para cada computador, por isso não posso simplesmente executar uma referência no meu computador pessoal ...


4


origem


Respeitando as respostas (corretas e precisas) dadas, não há garantia de que o programa funcionará melhor com um número máximo de threads do que com um único (ou seja, pode ser programado melhor para um único thread, algum thread pode retardar o processo geral, etc), embora, se for programado, devemos. Como mostra o consenso geral, a melhor coisa a fazer é comparar cada configuração com um conjunto de testes limitado. - Doktoro Reichard
Você deveria apenas medir isso. - Der Hochstapler


Respostas:


Idealmente, a contagem total de encadeamentos para todos os trabalhos deve ser o número de núcleos do sistema, exceto em sistemas que suportam hyper-threading, nos quais deve ser o dobro do número de núcleos. Portanto, se o sistema não tiver hyper-threading, existem 8 cálculos em execução, cada um deve ser executado em um thread.

Muitos processadores Intel vêm com hyper-threading, então cada núcleo pode suportar dois threads. Por exemplo, um sistema de 8 núcleos que suporte hyper-threading deve ter 16 threads para utilizar o sistema completamente.


5





A resposta depende do que o processo faz e como seu multi-threading foi programado, o que significa que você precisará experimentar.

Se o processo usa semáforos e outros mecanismos de exclusão para contenção entre os encadeamentos em recursos comuns (como memória), então, menos é o número de encadeamentos no processo, menos é o número de conflitos que causam esperas.

Durante uma espera, o encadeamento não faz nada, portanto, as esperas terão um efeito negativo na taxa de transferência. Nesse caso, mais processos e menos encadeamentos por processo melhorarão a taxa de transferência, então 8x8 terá um desempenho melhor que 1x64.

Por outro lado, se cada thread é totalmente isolado e não há compartilhamento comum recursos, então o sistema operacional irá agendar os threads sem qualquer distinção entre os dois casos de 8x8 ou 1x64. Neste caso, apenas o número total de threads é importante para o throughput total, então ambos os casos são de igual desempenho.


3



Como sua atualização diz que os computadores estão muito ocupados, muitos threads terão o efeito oposto de desacelerar o computador. Alternar a CPU entre threads é uma operação dispendiosa. - harrymc


O número correto depende de quanto tempo os processos gastam bloqueados no IO.

O livro "Programação de Concorrência na JVM" tem algumas boas informações sobre isso:

"Determinando o número de segmentos". Para um problema grande, gostaríamos de ter pelo menos tantos threads quanto o número de núcleos disponíveis. Isso garantirá que tantos núcleos quanto disponíveis para o processo sejam colocados em funcionamento para resolver nosso problema ...

Portanto, o número mínimo de encadeamentos é igual ao número de núcleos disponíveis. Se todas as tarefas forem intensivas em computação, isso é tudo o que precisamos. Ter mais threads será realmente prejudicial neste caso porque os núcleos seriam alternância de contexto entre threads quando ainda há trabalho a ser feito. Se as tarefas são intensivas em E / S, então devemos ter mais threads.

Quando uma tarefa executa uma operação de E / S, seu encadeamento fica bloqueado. O processador imediatamente muda o contexto para executar outros encadeamentos elegíveis. Se tivéssemos apenas tantos segmentos quanto o número de núcleos disponíveis, mesmo que tenhamos tarefas a executar, eles não poderão ser executados porque não os agendamos em threads para os processadores atenderem.

Se as tarefas passarem 50% do tempo bloqueadas, o número de threads deve ser o dobro do número de núcleos disponíveis. Se eles gastam menos tempo sendo bloqueados - isto é, são intensivos em computação - então devemos ter menos threads, mas não menos que o número de núcleos. Se eles gastam mais tempo sendo bloqueados - isto é, eles são IO intensivos - então devemos ter mais threads, especificamente, vários múltiplos do número de núcleos.

Assim, podemos calcular o número total de encadeamentos que precisamos da seguinte forma:

Número de linhas = número de cores disponíveis / (1 - coeficiente de bloqueio)

Se você precisar executar vários cálculos simultaneamente, talvez veja se é possível executá-los em um processo com um conjunto de encadeamentos dimensionado adequadamente.

Caso contrário, se você tiver o número ideal de encadeamentos para um cálculo, mas depois executar 8 de cada vez, poderá ter muitos.

A melhor solução é compará-lo experimentalmente.

Não sei exatamente o que você quer dizer com estacionamento central, mas a CPU tende a continuar executando o mesmo thread em um determinado núcleo por motivos de cache, embora também o mova algumas vezes por diferentes razões de calor / energia. Você pode investigar isso usando uma ferramenta como htop.


2



O negócio é que os computadores pertencem à minha universidade, por isso estão sempre ocupados. Em outras palavras, sua carga de trabalho varia de uma maneira incontrolável para mim, porque outras pessoas estão usando esses PCs também para seus cálculos, tornando a experimentação impossível. - theGD
AE / S está longe de ser o único recurso compartilhado entre os threads. - harrymc


Você respondeu a pergunta a si mesmo. "os computadores pertencem à minha universidade, então eles estão ocupados o tempo todo"

Você na verdade só recebe uma fatia dos processadores. Para fazer o trabalho da maneira mais eficiente, a sobrecarga de tarefas de comutação e multiplex, e os recursos em espera devem ser minimizados, assim você deve sempre considerar fazer um único thread.

Multi-threading sempre menos eficiente quando calculado com base em "poder de processamento" por causa da sobrecarga de comutação de contexto. Apenas acelera os problemas para utilizar todos os recursos desocupados "livres". idéia: use 8 computadores para executar um problema em provavelmente 7,9 vezes mais rápido, o que nunca pode ser maior que 8.

Se todos estes são dedicados a você, basta fazê-lo em paralelo para acelerar, se não, manter um único segmento e deixar que outros usem o núcleo restante para outro trabalho.

a propósito, de uma maneira egoísta, existem ferramentas de chapéu vermelho que chamam de grade que pode dividir seu trabalho em todo o linux do campus. (> 200). Ele vai correr tão rápido, só não seja pego, pois vai desacelerar todo mundo. ou use as ferramentas antigas, mathlab parallel.


1