Os núcleos da GPU podem executar muitos segmentos ao mesmo tempo, devido à maneira como eles alternam entre os segmentos para latência oculta . De fato, você precisa para executar muitos threads por núcleo para utilizar totalmente sua GPU.
Uma GPU está profundamente canalizada , o que significa que mesmo que novas instruções estejam iniciando a cada ciclo, cada instrução individual pode levar muitos ciclos para executar. Às vezes, uma instrução depende do resultado de uma instrução anterior, portanto, ela não pode ser iniciada (insira o pipeline) até que a instrução anterior seja concluída (sai do pipeline). Ou pode depender de dados da RAM que levarão alguns ciclos para serem acessados. Em uma CPU, isso resultaria em uma " barraca de oleoduto " (ou "bolha"), que sai parte do pipeline parado ocioso por vários ciclos, apenas aguardando o início da nova instrução. Isso é um desperdício de recursos de computação, mas pode ser inevitável.
Ao contrário de uma CPU, um núcleo de GPU é capaz de alternar entre threads muito rapidamente - na ordem de um ciclo ou dois. Assim, quando um thread trava por alguns ciclos porque sua próxima instrução não pode ser iniciada ainda, a GPU pode simplesmente passar para outro thread e iniciar sua próxima instrução. Se esse encadeamento parar, a GPU alterna os encadeamentos novamente e assim por diante. Esses encadeamentos adicionais estão fazendo um trabalho útil em estágios de pipeline que, de outra forma, teriam ficado ociosos durante esses ciclos, portanto, se houver encadeamentos suficientes para preencher os espaços um do outro, a GPU pode funcionar em todos os estágios do pipeline em cada ciclo. A latência em qualquer thread é ocultada pelos outros threads.
Este é o mesmo princípio subjacente ao recurso Hyper-threading da Intel, que faz com que um único núcleo apareça como dois núcleos lógicos. No pior dos casos, os encadeamentos executados nesses dois núcleos competirão entre si por recursos de hardware, e cada um deles funcionará a metade da velocidade. Mas em muitos casos, um thread pode utilizar recursos que o outro não pode - ALUs que não são necessárias no momento, estágios de pipeline que ficariam ociosos devido a paralisações - para que ambos os threads rodem a mais de 50% da velocidade eles alcançariam se corressem sozinhos. O design de uma GPU basicamente estende esse benefício para mais de dois threads.
Você pode achar útil ler o Guia de Melhores Práticas da CUDA , especificamente capítulo 10 ("Execução Configuration Optimizations "), que fornece informações mais detalhadas sobre como organizar seus threads para manter a GPU ocupada.