作業効率の高いバージョンではより多くのステップが必要ですが、アクティブスレッドの数がより速く減少し、すべての反復にわたるアクティブスレッドの総数がかなり少なくなるという事実によって相殺されます。反復中にワープにアクティブなスレッドがない場合、そのワープは次のバリアにスキップして中断され、他のワープを実行できます。そのため、アクティブワープを少なくすることで、実行時間を短縮できます。(これは、アクティブスレッドができるだけ少ないワープにまとめられるようにGPUコードを設計する必要があることを意味します。1つのアクティブスレッドでもワープ全体を強制するため、それらが散在することは望ましくありません。アクティブになります。)
単純なアルゴリズムのアクティブなスレッドの数を考慮してください。この記事の図2を見ると、k番目の反復の最初の2 kを除くすべてのスレッドがアクティブであることがわかります。したがって、Nスレッドでは、アクティブスレッドの数はN ‒ 2 kのようになります。たとえば、N = 1024の場合、反復ごとのアクティブスレッドの数は次のとおりです。
1023, 1022, 1020, 1016, 1008, 992, 960, 896, 768, 512
これをアクティブなワープの数に変換すると(32で割って切り上げる)、次のようになります。
32, 32, 32, 32, 32, 31, 30, 28, 24, 16
一方、作業効率の良いアルゴリズムは、半分のスレッドで開始し、その後、各反復でアクティブなスレッドの数を半分に減らして1になります。再び配列サイズの半分:
512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512
これをアクティブワープに変換します。
16, 8, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16
合計は71で、これはわずか4分の1です。したがって、作業全体の過程で、作業効率の良いアルゴリズムを使用すると、アクティブワープの数がはるかに少なくなることがわかります。(実際、中央で長時間実行する場合、アクティブワープはほんのわずかです。つまり、チップの大部分は占有されていません。たとえば、他のCUDAストリームから追加の計算タスクが実行されている場合、空きスペース。)