頂点シェーダーの頂点の半分を移動したいシェーダーがあります。パフォーマンスの観点からこれを行うための最良の方法を決定しようとしています。これは、100,000をはるかに超える頂点を処理しているため、速度が重要です。私は3つの異なるメソッドを見てきました:(擬似コードですが、あなたにアイデアを与えるのに十分です。<complex formula>
私は与えることはできませんが、それはsin()
関数と関数呼び出しを含むと言うことができます(ただ数値ですが、それでも関数呼び出し)、および浮動小数点数の基本的な算術の束)。
if (y < 0.5)
{
x += <complex formula>;
}
<complex formula>
これには、が半分の時間しか実行されないという利点がありますが、欠点は、分岐が確実に発生することです。これは、実際には数式よりも遅くなる可能性があります。これは最も読みやすいですが、このコンテキストでは読みやすさよりも速度を重視しています。
x += step(y, 0.5) * <complex formula>;
HLSLのstep()関数(最初のパラメーターが大きい場合は0を返し、小さい場合は1を返す)を使用すると、ブランチを削除できますが、今で<complex formula>
は毎回呼び出され、その結果は0で乗算されます(したがって、無駄な労力)半分の時間。
x += (y < 0.5) ? <complex formula> : 0;
これは私にはわかりません。?:
原因は分岐しますか?そうでない場合は、方程式の両側が評価されますか、それとも関連する側だけが評価されますか?
最後の可能性は、<complex formula>
がGPUではなくCPUにオフロードされる可能性があることですが、sin()やその他の操作の計算が遅くなり、正味の損失が発生する可能性があるのではないかと心配しています。また、もう1つの数値をシェーダーに渡す必要があり、オーバーヘッドも発生する可能性があります。誰が最善の行動方針であるかについて何か洞察を持っていますか?
補遺:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb509665%28v=vs.85%29.aspxによると
step()
関数は内部的に使用するので?:
、おそらく私の3番目のソリューションよりも優れているわけで<complex formula>
はなく、毎回確実に呼び出されるため、潜在的に悪化しますが、ストレートでは半分の時間しか呼び出されない可能性?:
があります。(まだ誰も質問のその部分に答えていません。)両方を避けて使用していますが:
x += (1.0 - y) * <complex formula>;
どこにも比較が行われていないので、それらのどれよりも優れている可能性があります。(そしてy
、常に0または1のいずれかです。)それでも<complex formula>
不必要に半分の時間で実行されますが、分岐を完全に回避する価値があるかもしれません。