2012-03-28 20 views
10

私がダウンして、カーネルのうち、パフォーマンスの最後のビットを圧迫することになっているとき、私は通常ビット演算子&|)で論理演算子&&||)を交換しても少し速くカーネルを作ることを見つけます。これは、CUDA Visual Profilerのカーネル時間の要約を見ることで確認できました。CUDA:なぜビット演算子が論理演算子より速いのですか?

なぜ、ビット演算子は、CUDAの論理演算子よりも速くですか?私は彼らがではないことを認めなければならない。が速いが、多くは時間がかかる。私はこの魔力がどんなスピードアップをもたらすのだろうかと思います。

免責事項:論理演算子の短絡およびビット単位の演算子は認識していません。私は、これらの演算子が間違ったコードの結果として誤用される可能性があることを十分に認識しています。結果として得られるロジックが同じままである場合に限り、この置換えを注意して使用します。スピードアップとスピードアップが私にとって重要です:-)

+0

最適化のヒントありがとうございました! –

+0

ロジャー:喜んで助けてください!私はこれを発見したときに驚いた:-) –

答えて

11

論理演算子は、特に短絡評価の規則を遵守する必要がある場合に、分岐を生じることがよくあります。通常のCPUの場合、これは分岐の予測ミスを意味する可能性があり、CUDAの場合はワープの分岐を意味する可能性があります。ビット単位の演算は、短絡評価を必要としないので、コードフローは線形(すなわち、分岐なし)である。

+1

また、論理演算子の場合、0以外の結果は1に設定する必要があります。 –

+1

@Roger:trueですが、これは最適化することができます。式が条件式の一部として使用されている場合は、変数に代入されている場合は結果を1に設定する必要があります。 –

1

ハードウェアレベルのレジスタでビット単位の演算を実行できます。レジスタ操作が最も高速ですが、これはデータがレジスタに収まる場合に特に当てはまります。論理演算には、式の評価が含まれます。通常、&、|、^、>> ...は最も高速な演算の一部であり、高性能ロジックで広く使用されています。

6

& & B:

if (!A) { 
    return 0; 
} 
if (!B) { 
    return 0; 
} 
return 1; 

が& B:

return A & B; 

これらは、AとBの評価は副作用を持つことができることを考えると意味論です(彼らは状態を変更する関数にすることもできます評価されたシステムの)。

AとBの種類とコンテキストに応じて、コンパイラがA && Bのケースを最適化できる方法はたくさんあります。