Digamos que eu tenha uma CPU de servidor com 18 núcleos, com hyperthreading ativado, o que significa que eu posso ver 36 cpus no htop.
Para utilizar totalmente a CPU e não afetar o desempenho de thread único, devo ter como objetivo que todos os 36 "núcleos" sejam executados a 100%, e os núcleos HT farão menos trabalho e ainda reportarão 100%, ou isso significaria o os núcleos "completos" já estão sendo interrompidos pela tarefa em seu "núcleo HT" e, portanto, realizando menos trabalhos de thread único?
Estou ciente de que existem muitas variáveis que afetam o desempenho do HT, só quero saber o que os medidores de CPU significam ao lidar com o HT.
hyperthreading
Tassadar
fonte
fonte
Respostas:
Se é permitido que o segundo núcleo virtual contribua quando o primeiro seria bloqueado, é melhor que não , então você realiza (pelo menos) um pouco de trabalho extra.
A questão é: quando ter dois threads diferentes faz com que um funcione pior? A previsão do ramo e as dependências entre as instruções não serão alteradas. Aguardando acesso à memória agora ... os dois threads competem pelo acesso à memória, tanto na utilização do cache quanto na largura de banda.
Se você tem algumas CPUs executando com HT e outras não, isso também significa que você atribuirá threads específicos a um tipo ou outro? Acho que não: seus programas executam seus threads em núcleos virtuais aleatórios. Então, como a divisão da configuração ajuda? Como cada CPU possui seu próprio cache, o único efeito é devido à largura de banda da memória e ao ônus da coerência do cache.
Em geral, você chega a um ponto em que ter algo mais a fazer pode ser mais caro do que deixar algumas unidades de execução da CPU ociosas. Isso não depende diretamente do número de threads, mas do que os threads estão fazendo e da arquitetura detalhada da memória e das nuances de desempenho dos vários componentes.
Não existe uma resposta simples. Mesmo com um programa específico em mente, a máquina pode ser diferente da das pessoas que relatam suas próprias experiências.
Você deve tentar e medir o que é mais rápido, com esse trabalho específico nessa máquina exata. E mesmo assim, isso pode mudar com as atualizações de software e a mudança de uso ao longo do tempo.
Dê uma olhada no volume 3 da magnum opus da Anger . Se você observar atentamente algum processador específico, poderá encontrar recursos limitantes no pipeline profundo de muitas etapas necessárias para executar o código. Você precisa encontrar um caso em que o comprometimento excessivo faça com que ele seja executado mais lentamente, em vez de não levar mais trabalho. Em geral, isso significaria algum tipo de cache; e onde o recurso é compartilhado entre threads.
O que significa o medidor de CPU: ele relata o tempo todo que não é gasto executando o encadeamento ocioso. Os dois encadeamentos lógicos atribuídos a um núcleo não ficarão ociosos, mesmo que o trabalho real realizado em um deles possa ser pequeno. O tempo gasto com o pipeline travou por alguns ciclos até que os resultados estejam prontos, a memória é buscada, as operações atômicas são protegidas etc. etc. também não fazem com que o encadeamento seja arquivado como "não pronto", para que não fique ocioso, e o tempo ainda aparece como em uso. Esperar na RAM não será exibido como ocioso. Somente algo como E / S fará com que o encadeamento bloqueie e pare o tempo de carregamento. Um mutex de sistema operacional em geral fará isso, mas com o surgimento de sistemas multicore, isso não é mais certo, pois um "spinlock" não fará com que o encadeamento volte à prateleira.
Portanto, um medidor de CPU de 100% não significa que tudo corre bem, se a CPU geralmente fica presa à espera de memória. Um número menor de núcleos lógicos mostrando 90% poderia muito bem estar realizando mais trabalho, pois termina o processamento de números e agora está aguardando no disco.
Portanto, não se preocupe com o medidor de CPU. Olhe para o progresso real feito, única .
fonte
Os medidores de CPU são muito ruins para dizer a você quanto mais desempenho você pode extrair de suas CPUs com hyperthread. Para isso, você deve executar seus próprios benchmarks com várias taxas de assinatura física por núcleo. Existem algumas cargas de trabalho que funcionam melhor com o HT completamente desativado, portanto inclua esse caso também em seus testes. Pode ser 1: 2 (36 trabalhadores paralelos), ou 1: 1,5, ou até 1: 2,5! Depende da sua carga de trabalho.
Mais detalhadamente, o HT é implementado no silício de maneira a reduzir o tempo que o processador passa ocioso quando um contexto precisa ser alternado ou uma predição de ramificação falha. Isso facilita atingir 100% de uso da unidade de execução do que com truques puros do sistema operacional. O HT evoluiu desde sua introdução, e há mais paralelismo nos chips modernos do que aqueles que estávamos usando há 10 anos.
Existem dois perfis de execução que afetarão onde está o ponto ideal de excesso de assinatura:
fonte
Você deve ver todos os 36 núcleos em execução a 100% - supondo que o software possa fazer isso (o que não é trivial - a programação pode ser complicada com muitos núcleos, portanto, quedas abaixo de 100% são aceitáveis).
Obviamente, quando você "divide" um minério com hyperthreading, o significado desses 200% não é "2x100% - no trabalho realizado. Mas isso é invisível a qualquer medição realizada (proveniente da utilização da CPU e sem nenhum conceito de trabalho realizado). A quantidade de trabalho realizado depende do que é o trabalho - em algum lugar acima de 1,5 x o trabalho sem hiper-segmentação é esperado na maioria das vezes.
fonte
A maneira como o hyperthreading é implementado varia de acordo com o uarch específico da CPU. De Nehalem a Skylake, a Intel reduziu significativamente as partes compartilhadas de proporção fixa (ou seja: 50/50) do oleoduto, indo para estruturas compartilhadas dinamicamente.
De qualquer forma, em termos gerais, ativar o HT levou a uma execução de thread único ligeiramente mais lenta, mas devido à maneira como o agendador do Linux funciona, isso só acontece quando o número ou o thread em execução é maior que o número de núcleos físicos. Como em tais situações (quando threads> núcleos), você normalmente valoriza a taxa de transferência total da máxima importância, o hyperthreading permanece uma vitória líquida.
Como isso é possível? O ponto principal a entender é que a CPU não apresenta os núcleos físicos e os virtuais como núcleos iguais, mas expõe os últimos de uma maneira que o planejador do Linux pode evitar agendá-los se houver outros núcleos físicos disponíveis. Em outras palavras, ele primeiro usa todos os núcleos físicos, depois começa a usar o virtual.
Isso significa que, geralmente, o HyperThreading é um recurso muito valioso (outros processadores, como o Power8, usa técnicas SMT ainda mais profundas) e que, para maximizar o rendimento, você deve habilitá-lo, carregando a CPU com pelo menos um encadeamento por núcleo virtual ou físico. Para um exemplo prático, para extrair o desempenho completo de uma CPU de 18 núcleos, você deve usar pelo menos 36 threads.
Existem duas exceções:
fonte