今日の最新のプロセッサでは、分岐条件の大なり記号と大なり記号の比較の間にパフォーマンスの違いはありますか?>
私が同じように簡単にどちらかになる可能性のある状態を持っている場合、どちらかを選択することにわずかな利点がありますか、>=
またはその逆ですか?(これは、IntelまたはAMDハードウェアでコンパイルされた言語用です)
3 に答える
異なる述語の計算方法のために、異なる述語の比較に目立った違いはないはずです(x86のマニュアルを詳しく読んでいないので、動作が異なる可能性があることに注意してください)。
ほとんどの命令は、副産物としていくつかのフラグを生成します。通常、少なくともキャリー(c)、オーバーフロー(o)、ゼロ(z)、および負(n)があります。
xy命令(上記の4つを確実に作成する)によって作成された述語を使用すると、必要なすべての比較を簡単に理解できます。符号なし番号の場合:
x = y z
x != y !z
x < y !c
x <= y !c + z
x > y c . !z
x >= y c
したがって、ほとんど違いはありません。ただし、いくつかの違いがあります。これは主に、TEST(完全な減算ではなくAND)を使用できるか、CMP(減算)を使用する必要があるかどうかに起因します。TESTはより制限されていますが、より高速です(通常)。
また、最新のアーキテクチャ(Intel側のc2dから開始)では、2つのµopsを1つのマクロopに融合できる場合があります。これはいわゆるmacro-op融合であり、いくつかの優れた利点があります。そして、そのためのルールは、あるアーキテクチャから次のアーキテクチャに変わり、少し長くなります。たとえば、オーバーフロー、パリティ、または符号フラグのみをテストするブランチ(JO、JNO、JP、JNP、JS、JNS)は、TESTと融合できますが、c2dおよびnehalemsのCMPとは融合できません(私はそれを調べたに違いありません-セクション7.5) 。
それで、それは複雑で、そのようなことを心配しないと言うことができますか?これは、コンパイラのオプティマイザを作成している場合を除きます。これは、ソースコードに何を記述したかに関係なく、コンパイラはとにかく必要な処理を実行するためです。また、正当な理由があります(つまり、JGEが理論的に高速だった場合は通常、(x <y)の場合に書き込みます。そして、本当に1つのアドバイスが必要な場合は、0との比較の方が速いことがよくあります。
基礎となる実装がALU/FPUでどのように行われるかはよくわかりませんが、それらすべてに対して1つの操作のみが必要です(つまり、プリミティブ型に対して)
興味があり、最適化しようとしているのではないので、これが単なる質問であることを心から願っています。これによってパフォーマンスが大幅に向上することはなく、コードにはるかに悪いパフォーマンスの問題が含まれる可能性があります。
次の1つだけを使用して、すべての関係演算子をイベント実装できます。
a<bがベースです a> b == b <a a> = b ==!(a <b) a <= b ==!(a> b)
もちろん、これはCPUでの実装方法ではなく、よりトリビアです。
違いがあるのではないかと真剣に疑っています。