Sebbene la versione efficiente dal punto di vista del lavoro richieda più passaggi, ciò è compensato dal fatto che il numero di thread attivi diminuisce più rapidamente e il numero totale di thread attivi su tutte le iterazioni è considerevolmente più piccolo. Se un ordito non ha thread attivi durante un'iterazione, quell'ordito salterà semplicemente alla seguente barriera e verrà sospeso, consentendo l'esecuzione di altri orditi. Quindi, avere meno orditi attivi può spesso ripagare in tempo di esecuzione. (In questo è implicito che il codice GPU deve essere progettato in modo tale che i thread attivi siano raggruppati nel minor numero possibile di orditi - non si desidera che siano sparsi scarsamente, poiché anche un solo thread attivo forzerà l'intero ordito per rimanere attivo.)
Considera il numero di thread attivi nell'algoritmo ingenuo. Osservando la figura 2 nell'articolo, si può vedere che tutti i fili sono attivi tranne per i primi 2 k il k esima iterazione. Quindi con N thread, il numero di thread attivi va come N - 2 k . Ad esempio, con N = 1024, il numero di thread attivi per iterazione è:
1023, 1022, 1020, 1016, 1008, 992, 960, 896, 768, 512
Se lo converto in numero di orditi attivi (dividendo per 32 e arrotondando per eccesso), ottengo:
32, 32, 32, 32, 32, 31, 30, 28, 24, 16
per una somma di 289. D'altra parte, l'algoritmo efficiente dal punto di vista lavorativo inizia con la metà del numero di thread, quindi dimezza il numero di quelli attivi su ciascuna iterazione fino a quando non scende a 1, quindi inizia a raddoppiare fino a quando non torna a metà della dimensione dell'array di nuovo:
512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512
Convertire questo in orditi attivi:
16, 8, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16
La somma è 71, che è solo un quarto in più. Quindi puoi vedere che nel corso dell'intera operazione, il numero di orditi attivi è molto più piccolo con l'algoritmo efficiente dal punto di vista del lavoro. (In effetti, per una lunga corsa nel mezzo ci sono solo una manciata di orditi attivi, il che significa che la maggior parte del chip non è occupata. Se ci sono attività di calcolo aggiuntive in esecuzione, ad esempio da altri flussi CUDA, potrebbero espandersi per riempire quello spazio libero.)