Ïf ステートメントは、条件付き移動を利用できない限り条件付きジャンプを生成しますが、それは手書きのアセンブリで行われる可能性が高いです。ルールに沿って動作する条件付きジャンプのペナルティが許容されるように、CPU の条件付きジャンプの仮定 (分岐予測) を管理するルールがあります。次に、物事をさらに複雑にするための順不同の実行があります:)。肝心なのは、コードが単純であれば、最終的に発生するジャンプによってパフォーマンスが台無しになることはないということです。Agner Fog の最適化ページをチェックしてみてください。
特に、C コードの非デバッグ コンパイルでは、4 つの条件付きジャンプが生成されるはずです。論理積 (&&) と括弧を使用すると、左から右へのテストが行われるため、C の最適化の 1 つは、最初に >0.0f である可能性が最も高い f32 をテストすることです (そのような確率が決定できる場合)。5 つの可能な実行バリアントがあります。
t1tbt ; var.m128_f32[0] <= 0.0f
t1fnb t2tbt ; var.m128_f32[0] > 0.0f, var.m128_f32[1] <= 0.0f
t1fnb t2fnb t3tbt ; var.m128_f32[0] > 0.0f, var.m128_f32[1] > 0.0f,
; var.m128_f32[2] <= 0.0f
t1fnb t2fnb t3fnb t4tbt ; var.m128_f32[0] > 0.0f, var.m128_f32[1] > 0.0f,
; var.m128_f32[2] > 0.0f, var.m128_f32[3] <= 0.0f
t1fnb t2fnb t3fnb t4fnb ; var.m128_f32[0] > 0.0f, var.m128_f32[1] > 0.0f
; var.m128_f32[2] > 0.0f, var.m128_f32[3] > 0.0f
発生した分岐のみがパイプラインの中断を引き起こし、分岐予測は中断を可能な限り最小限に抑えます。
float はテストにコストがかかると仮定すると (実際にそうです)、var が共用体であり、浮動小数点のインとアウトに精通している場合は、オーバーラップする型で整数テストを行うことを検討できます。たとえば、格納された値 1.0f は、0x00、0x00、0x80、0x3f (x86/リトルエンディアン) として格納された 4 バイトを占有します。この値を長整数として読み取ると、0x3f800000 または +1065353216 が得られます。0.0f は 0x00、0x00、0x00、0x00 または 0x00000000 (ロング) です。負の float 値は、最上位ビットが設定されている (0x80000000) ことを除いて、正の値とまったく同じ形式です。