Embora a versão com eficiência de trabalho exija mais etapas, isso é compensado pelo fato de o número de encadeamentos ativos diminuir mais rapidamente e o número total de encadeamentos ativos em todas as iterações ser consideravelmente menor. Se um warp não tiver threads ativos durante uma iteração, ele simplesmente pulará para a barreira a seguir e será suspenso, permitindo que outros warps sejam executados. Portanto, ter menos distorções ativas geralmente pode render em tempo de execução. (Implícito nisso é que o código da GPU precisa ser projetado de forma que os threads ativos sejam agrupados no menor número possível de warps - você não deseja que eles sejam dispersos esparsamente, pois mesmo um thread ativo forçará todo o warp para permanecer ativo.)
Considere o número de threads ativos no algoritmo ingênuo. Observando a Figura 2 no artigo, é possível ver que todos os encadeamentos estão ativos, exceto os primeiros 2 k na k- ésima iteração. Assim, com N threads, o número de threads ativos é de N - 2 k . Por exemplo, com N = 1024, o número de encadeamentos ativos por iteração é:
1023, 1022, 1020, 1016, 1008, 992, 960, 896, 768, 512
Se eu converter isso para o número de warps ativos (dividindo por 32 e arredondando para cima), obterá:
32, 32, 32, 32, 32, 31, 30, 28, 24, 16
por uma soma de 289. Por outro lado, o algoritmo eficiente em termos de trabalho começa com metade do número de threads e reduz pela metade o número de ativos em cada iteração até chegar a 1, depois começa a dobrar até voltar a metade do tamanho da matriz novamente:
512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512
Convertendo isso em warps ativos:
16, 8, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16
A soma é 71, o que representa apenas um quarto do total. Assim, você pode ver que, ao longo de toda a operação, o número de warps ativos é muito menor com o algoritmo de trabalho eficiente. (De fato, para uma longa execução no meio, existem apenas alguns warps ativos, o que significa que a maior parte do chip não está ocupada. Se houver tarefas adicionais de computação em execução, por exemplo, de outros fluxos CUDA, elas poderão se expandir para preencher essa lacuna. espaço desocupado.)