Por que 16 threads são mais eficientes que 8 em um i7 com 4 núcleos hiperthreaded? (Robocópia)

Por que 16 threads são mais eficientes que 8 em um i7 com 4 núcleos hiperthreaded? (Robocópia)

No Windows 8.1, estou usando o Robocopy para salvar dados de 2 servidores no espaço de armazenamento de um PC dedicado. O volume de dados é de 147.314 arquivos em 4.110 pastas (66.841.845.760 bytes).

Todos os 3 PCs envolvidos possuem CPU i7 com 4 núcleos e estão em uma rede de 1 Gb. O espaço de armazenamento do alvo (espelhado e distribuído em D:) é realizado usando um gabinete JBOD de 4 x 4 TB.

Devido aos 4 núcleos e ao hyperthreading das CPUs, eu esperava que a opção Robocopy /MT:8 funcionasse melhor e que mais de 8 threads seriam um exagero devido ao gerenciamento de threads não beneficiário.

Eu testei isso. Listo aqui os dados da quarta série de testes (duração em mm:ss):

 1 thread:  59:19
 2 threads: 39:12
 4 threads: 29:13
 8 threads: 24:36
16 threads: 24:19
32 threads: 24:27

É verdade que os poucos segundos usando 16 threads são insignificantes, maseles são consistentesem todas as séries de testes, ou seja, não devido a mais carga no teste com menos de 16 threads (a menos que este tenha sido o caso em todas as 4 séries de testes). Observe também que 32 threads são quase sempre um pouco mais rápidos que 8 threads.

Pergunta: qual motivo técnico é responsável pelo uso de 16 threads ser mais eficiente que 8 threads em um i7 com 4 núcleos hyperthreaded?

Responder1

Versão TL; dr: se você estivesse fazendo algo que usasse muito a CPU, como transcodificar vídeo usando o Handbrake, não gostaria de usar mais núcleos do que CPUs, pois não haveria lugar para o trabalho ser feito. Neste caso, onde a maioria dos threads passará 90% do tempo dormindo, aguardando leituras ou gravações, ter mais threads funcionaparavocê e não contra.


Copiar arquivos não é uma tarefa particularmente dependente da CPU. Embora ter mais núcleos possa ajudar a evitar que outras tarefas bloqueiem sua ferramenta de cópia, é improvável que cada thread esteja sendo executado perto de 100% em cada núcleo.

Cada thread de cópia enviará uma solicitação de leitura ao disco rígido e, em seguida, entrará em suspensão enquanto aguarda que a solicitação de leitura seja atendida. Seu disco enferrujado giratório geralmente tem um tempo de busca de 9 milissegundos, praticamente uma eternidade em termos de CPU, e a tarefa de cópia não simplesmente giraria dizendo "já está pronto?" e desperdiçando ciclos de CPU. Fazer isso bloquearia esse thread em 100% da CPU e desperdiçaria recursos. Não, o que acontece é que o thread emite uma leitura e é colocado em suspensão até que a leitura seja concluída e os dados estejam prontos para a próxima etapa.

Enquanto isso, outro thread faz o mesmo, é bloqueado em uma leitura e colocado em suspensão. Isso acontece para todos os 16 threads. (Na realidade, suas leituras e gravações acontecerão em momentos aleatórios à medida que ficam fora de sincronia, mas essa é a ideia)

Depois que um dos threads tiver dados prontos, o Windows os reagendará e começará a processá-los para serem gravados. No que diz respeito ao segmento, o processo é o mesmo. Diz "gravar esses dados no arquivo x no local y" e o Windows pega os dados e desagenda o thread. O Windows faz o trabalho em segundo plano para descobrir onde o arquivo está, move os dados (potencialmente pela rede, adicionando mais milissegundos ao atraso) e, em seguida, retorna o controle ao thread assim que a gravação for bem-sucedida.

Nenhum thread estará queimando o tempo todo em um núcleo de CPU e, portanto, mais threads do que CPUs não são um problema. Nenhum thread ficará acordado por tempo suficiente para que isso seja um problema.

Se você tivesse apenas uma única CPU com muitos outros threads em execução, poderia haver gargalos na CPU, mas em um sistema multicore com esse tipo de carga de trabalho, eu ficaria surpreso se a CPU fosse o problema.

É mais provável que você tenha gargalos no desempenho do disco rígido e atinja a profundidade da fila dos buffers de leitura ou gravação nas unidades. Ao usar mais threads você está empurrandoalgoaté seus limites, seja disco ou rede, e a única maneira de descobrir qual é o melhor número de threads é fazer o que você fez e experimentar.

Em um sistema com cópia de SSD para SSD, eu suspeitaria que um número menor de threads poderia ser melhor, pois haveria menos latência do que copiar arquivos de HDDs de ferrugem giratória, empurrando pela rede e gravando em ferrugem giratória, mas não tenho nenhuma evidência para apoiar essa suposição.

informação relacionada