CUDA Cベストプラクティスガイドには、符号付き整数と符号なし整数の使用に関する小さなセクションがあります。
C言語標準では、符号なし整数オーバーフローのセマンティクスは明確に定義されていますが、符号付き整数オーバーフローは未定義の結果を引き起こします。したがって、コンパイラーは、符号なし演算よりも符号付き演算の方が積極的に最適化できます。これは、ループカウンターで特に注意が必要です。ループカウンターは常に正の値を持つのが一般的であるため、カウンターを符号なしとして宣言したくなる場合があります。ただし、パフォーマンスを少し向上させるには、代わりに署名済みとして宣言する必要があります。
たとえば、次のコードについて考えてみます。
for(i = 0; i <n; i ++){ out [i] = in [offset + stride * i]; }ここで、部分式
stride*i
は32ビット整数をオーバーフローする可能性があるため、iが符号なしとして宣言されている場合、オーバーフローセマンティクスにより、コンパイラは、強度低下など、他の方法で適用された可能性のあるいくつかの最適化を使用できなくなります。代わりに、オーバーフローのセマンティクスが定義されていない場合に、iが署名済みとして宣言されている場合、コンパイラーはこれらの最適化を使用する余地があります。
特に最初の2つの文は私を混乱させます。符号なしの値のセマンティクスが明確に定義されており、符号付きの値が未定義の結果を生成する可能性がある場合、コンパイラーはどのようにして後者のより良いコードを生成できますか?