概要:
計算する最速の方法を探しています
(int) x / (int) y
の例外を得ることなくy==0
。代わりに、任意の結果が必要です。
バックグラウンド:
画像処理アルゴリズムをコーディングするとき、私はしばしば(累積された)アルファ値で除算する必要があります。最も単純なバリアントは、整数演算を行うプレーンCコードです。私の問題は、通常、を使用した結果ピクセルに対してゼロ除算エラーが発生することalpha==0
です。ただし、これは正確に結果がまったく問題にならないピクセルalpha==0
です。のピクセルのカラー値は気にしません。
詳細:
私は次のようなものを探しています:
result = (y==0)? 0 : x/y;
または
result = x / MAX( y, 1 );
xとyは正の整数です。コードはネストされたループで膨大な回数実行されるため、条件付き分岐を取り除く方法を探しています。
yがバイト範囲を超えない場合、私は解決策に満足しています
unsigned char kill_zero_table[256] = { 1, 1, 2, 3, 4, 5, 6, 7, [...] 255 };
[...]
result = x / kill_zero_table[y];
しかし、これは明らかに大きな範囲ではうまく機能しません。
私は最後の質問だと思います:他のすべての値を変更せずに0を他の整数値に変更する最速のビットいじくりハックは何ですか?
明確化
分岐が高すぎることは100%わかりません。ただし、異なるコンパイラが使用されているため、ほとんど最適化しないでベンチマークすることをお勧めします(これは確かに問題です)。
確かに、コンパイラーは少しいじくるときは素晴らしいですが、「ドントケア」の結果をCで表現できないため、コンパイラーは最適化の全範囲を使用することはできません。
コードは完全にC互換である必要があります。メインプラットフォームはLinux 64ビットで、gccとclang、MacOSを備えています。
y += !y
?それを計算するためにブランチは必要ありません。あなたは、比較可能性x / (y + !y)
に対してx / max(y, 1)
も多分とy ? (x/y) : 0
。少なくとも最適化がオンになっていると、どちらにも分岐はないと思います。
0
セクションが巨大で隣接している場合、現代の分岐予測は許容されます。マイクロ最適化をいじる場所があり、ピクセルごとの操作はまさにその場所です。