Digamos que eu tenho uma CPU de 4 núcleos e quero executar algum processo no período mínimo de tempo. O processo é idealmente paralelelizável, para que eu possa executar partes dele em um número infinito de threads e cada thread leva a mesma quantidade de tempo.
Como tenho 4 núcleos, não espero aceleração executando mais threads do que núcleos, pois um único núcleo é capaz de executar um único thread em um determinado momento. Eu não sei muito sobre hardware, então isso é apenas um palpite.
Existe um benefício em executar um processo paralelamente agradável em mais threads do que núcleos? Em outras palavras, meu processo terminará mais rápido, mais lento ou na mesma quantidade de tempo se eu o executar usando 4000 threads em vez de 4 threads?
fonte
Eu concordo com a resposta de @ Gonzalo. Eu tenho um processo que não executa E / S, e aqui está o que eu encontrei:
Observe que todos os encadeamentos funcionam em uma matriz, mas em intervalos diferentes (dois encadeamentos não acessam o mesmo índice); portanto, os resultados podem diferir se eles trabalharem em matrizes diferentes.
A máquina 1.86 é um macbook air com um SSD. O outro mac é um iMac com um disco rígido normal (acho que são 7200 rpm). A máquina Windows também possui um disco rígido de 7200 rpm.
Neste teste, o número ideal foi igual ao número de núcleos na máquina.
fonte
Sei que essa pergunta é bastante antiga, mas as coisas evoluíram desde 2009.
Há duas coisas a serem consideradas agora: o número de núcleos e o número de threads que podem ser executados em cada núcleo.
Nos processadores Intel, o número de threads é definido pelo Hyperthreading, que é apenas 2 (quando disponível). Mas o Hyperthreading reduz o tempo de execução em dois, mesmo quando não estiver usando 2 threads! (ou seja, 1 pipeline compartilhado entre dois processos - isso é bom quando você tem mais processos, e não é tão bom assim. Mais núcleos são definitivamente melhores!)
Em outros processadores, você pode ter 2, 4 ou até 8 threads. Portanto, se você tiver 8 núcleos, cada um deles suportando 8 threads, poderá ter 64 processos em execução em paralelo sem alternância de contexto.
"Nenhuma troca de contexto" obviamente não é verdadeira se você executar com um sistema operacional padrão que fará a troca de contexto para todos os tipos de outras coisas fora de seu controle. Mas essa é a ideia principal. Alguns sistemas operacionais permitem alocar processadores para que apenas seu aplicativo tenha acesso / uso do referido processador!
Pela minha própria experiência, se você possui muitas E / S, vários threads são bons. Se você tiver um trabalho intensivo em memória muito pesada (fonte de leitura 1, fonte de leitura 2, computação rápida, gravação), ter mais threads não ajuda. Novamente, isso depende da quantidade de dados que você lê / grava simultaneamente (ou seja, se você usa o SSE 4.2 e lê valores de 256 bits, que interrompe todos os threads em sua etapa ... em outras palavras, 1 thread é provavelmente muito mais fácil de implementar e provavelmente mais rápido, se não realmente mais rápido.Isso dependerá da sua arquitetura de processo e memória, alguns servidores avançados gerenciam intervalos de memória separados para núcleos separados, para que threads separados sejam mais rápidos, pressupondo que seus dados sejam arquivados corretamente ... e é por isso que, em alguns arquiteturas, 4 processos serão executados mais rapidamente que 1 processo com 4 threads.)
fonte
O desempenho real dependerá do rendimento voluntário de cada thread. Por exemplo, se os encadeamentos NÃO tiverem E / S e não usarem serviços do sistema (ou seja, eles são 100% ligados à CPU), então um encadeamento por núcleo é o ideal. Se os encadeamentos fizerem algo que exija espera, será necessário experimentar para determinar o número ideal de encadeamentos. 4000 threads acarretariam uma sobrecarga significativa na programação, portanto provavelmente também não é o ideal.
fonte
A resposta depende da complexidade dos algoritmos usados no programa. Eu vim com um método para calcular o número ideal de threads fazendo duas medições dos tempos de processamento Tn e Tm para dois números arbitrários de threads 'n' e 'm'. Para algoritmos lineares, o número ideal de encadeamentos será N = sqrt ((m n (Tm * (n-1) - Tn * (m-1))) / (n Tn-m Tm)).
Por favor, leia meu artigo sobre cálculos do número ideal para vários algoritmos: pavelkazenin.wordpress.com
fonte
Eu pensei em adicionar outra perspectiva aqui. A resposta depende se a pergunta está assumindo escala fraca ou escala forte.
Da Wikipedia :
Escala fraca: como o tempo de solução varia com o número de processadores para um tamanho de problema fixo por processador.
Escala forte: como o tempo de solução varia com o número de processadores para um tamanho total fixo do problema.
Se a pergunta está assumindo escala fraca, a resposta de @ Gonzalo é suficiente. No entanto, se a pergunta estiver assumindo uma escala forte, há algo a acrescentar. Em escala forte, você assume um tamanho fixo de carga de trabalho; portanto, se você aumentar o número de threads, o tamanho dos dados nos quais cada thread precisa trabalhar diminui. Nas CPUs modernas, os acessos à memória são caros e seria preferível manter a localidade mantendo os dados em caches. Portanto, o número ideal provável de threads pode ser encontrado quando o conjunto de dados de cada thread se encaixa no cache de cada núcleo (não entrarei em detalhes para discutir se é o cache L1 / L2 / L3 do sistema).
Isso vale mesmo quando o número de threads excede o número de núcleos. Por exemplo, suponha que haja 8 unidades arbitrárias (ou AU) de trabalho no programa que serão executadas em uma máquina de 4 núcleos.
Caso 1: execute com quatro threads em que cada thread precisa concluir 2AU. Cada thread leva 10s para ser concluído ( com muitas falhas de cache ). Com quatro núcleos, o tempo total será de 10s (10s * 4 threads / 4 núcleos).
Caso 2: execute com oito threads em que cada thread precisa concluir 1AU. Cada encadeamento leva apenas 2s (em vez de 5s devido à quantidade reduzida de erros de cache ). Com quatro núcleos, o tempo total será de 4s (2s * 8 threads / 4 núcleos).
Simplifiquei o problema e ignorei as despesas gerais mencionadas em outras respostas (por exemplo, alternâncias de contexto), mas espero que você entenda que pode ser benéfico ter mais número de threads do que o número disponível de núcleos, dependendo do tamanho dos dados ' está lidando com.
fonte
4000 threads ao mesmo tempo é bastante alto.
A resposta é sim e não. Se você estiver executando muitas E / S de bloqueio em cada encadeamento, sim, poderá mostrar acelerações significativas fazendo provavelmente 3 ou 4 encadeamentos por núcleo lógico.
Se você não estiver bloqueando muitas coisas, no entanto, a sobrecarga extra com a segmentação apenas a tornará mais lenta. Portanto, use um perfilador e veja onde estão os gargalos em cada peça possivelmente paralela. Se você estiver fazendo cálculos pesados, mais de 1 thread por CPU não ajudará. Se você estiver transferindo muita memória, também não ajudará. Se você estiver executando muitas E / S, como acesso ao disco ou à Internet, sim, vários threads ajudarão até certo ponto ou, pelo menos, tornarão o aplicativo mais responsivo.
fonte
Referência.
Eu começava a aumentar o número de threads para um aplicativo, começando em 1, e depois chegava a algo como 100, executava três e cinco tentativas para cada número de threads e desenvolvia um gráfico da velocidade de operação versus número de threads. .
Você deve considerar que a caixa de quatro threads é ideal, com leves aumentos no tempo de execução depois disso, mas talvez não. Pode ser que seu aplicativo seja limitado por largura de banda, ou seja, o conjunto de dados que você está carregando na memória é enorme, você está recebendo muitas falhas de cache etc., de modo que 2 threads são ideais.
Você não pode saber até testar.
fonte
Você encontrará quantos threads você pode executar em sua máquina executando o comando htop ou ps que retorna o número de processos em sua máquina.
Você pode usar a página de manual sobre o comando 'ps'.
Se você deseja calcular o número de processos de todos os usuários, pode usar um destes comandos:
ps -aux| wc -l
ps -eLf | wc -l
Calculando o número de um processo do usuário:
ps --User root | wc -l
Além disso, você pode usar "htop" [Referência] :
Instalando no Ubuntu ou Debian:
Instalando no Redhat ou CentOS:
Se você deseja compilar o htop a partir do código fonte, você o encontrará aqui .
fonte
O ideal é 1 thread por núcleo, desde que nenhum deles bloqueie.
Um caso em que isso pode não ser verdade: existem outros threads em execução no núcleo; nesse caso, mais threads podem fornecer ao seu programa uma fatia maior do tempo de execução.
fonte
Um exemplo de muitos threads ("pool de threads") versus um por núcleo é o da implementação de um servidor Web no Linux ou no Windows.
Como os soquetes são pesquisados no Linux, muitos threads podem aumentar a probabilidade de um deles pesquisar o soquete certo no momento certo - mas o custo geral de processamento será muito alto.
No Windows, o servidor será implementado usando portas de conclusão de E / S - IOCPs - que farão com que o aplicativo seja acionado: se uma E / S for concluída, o SO iniciará um thread em espera para processá-lo. Quando o processamento é concluído (geralmente com outra operação de E / S como em um par de solicitação-resposta), o encadeamento retorna à porta IOCP (fila) para aguardar a próxima conclusão.
Se nenhuma E / S foi concluída, não há processamento a ser feito e nenhum encadeamento é iniciado.
De fato, a Microsoft recomenda não mais que um thread por núcleo nas implementações do IOCP. Qualquer E / S pode ser conectada ao mecanismo IOCP. Os COI também podem ser publicados pelo aplicativo, se necessário.
fonte
timeout is an upper bound on the amount of time elapsed before select() returns. If both fields of the timeval structure are zero, then select() returns immediately. (This is useful for polling.) If timeout is NULL (no timeout), select() can block indefinitely.
falando do ponto de vista da computação e da memória vinculada (computação científica), 4000 threads tornarão o aplicativo muito lento. Parte do problema é uma sobrecarga muito alta da alternância de contexto e, provavelmente, uma localização de memória muito ruim.
Mas isso também depende da sua arquitetura. De onde ouvi os processadores Niagara, supostamente, são capazes de lidar com vários threads em um único núcleo usando algum tipo de técnica avançada de pipelining. No entanto, não tenho experiência com esses processadores.
fonte
Espero que isso faça sentido, verifique a utilização da CPU e da memória e coloque algum valor limite. Se o valor limite for ultrapassado, não permita criar novo encadeamento, senão permita ...
fonte