2

|の間に大きな違いはありますか?+ 長期的にはコードのパフォーマンスに影響を与えますか? それとも両方ともO(1)ですか? 私が取り組んでいるコードは次のようなものです:

uint64_t dostuff(uint64_t a,uint64_t b){
        // the max values of the inputs are 2^32 - 1

        // lots of stuff involving boolean operators
        // that have no way of being substituted by 
        // arithmetic operators

        return (a << 32) + b;
        //or
        return (a << 32) | b;
}

コードは何度も使用するので、できるだけ高速化したいと考えています。

4

8 に答える 8

5

最新のコンピューターではパフォーマンスの違いはありません。

ただし、2 つの演算子の意味は異なります。ビットが既に設定されている場合、|は何もしませんが、+そのビットとそれに続くゼロ以外のすべてのビットをクリアし、次のゼロ ビットを 1 に設定します。

于 2011-06-01T19:41:46.990 に答える
2

を使用し|ます。

+明らかな理由により、操作時間を増やすことしかできません。

于 2011-06-01T19:43:20.047 に答える
1

有利な点があるとすれば、有利になるでしょうor。ただし、実際には、合理的に最新の CPU (または非常に古いもの以外) で違いがある可能性はほとんどありませ

基本的に、orビットを設定するだけで、それだけです。必要なのは2 入力orゲートが 1 つだけなので、ちょうど 1 ゲートの伝搬遅延が得られます。

加算器はもう少し複雑です。現在のビットを計算するには、3 入力 XOR が必要です。XOR は通常、2 レベルのゲートで構成されます。さらに、次のビットの加算器への入力として使用する必要があるキャリーを生成します。したがって、「リップルキャリー加算器」は、追加されるビットと同じ数のクロックサイクルを必要とします。追加の残りの部分とは別にキャリーを処理するという問題を処理するより賢い方法があるため、伝搬遅延を低く抑えることができますが、最悪の場合、これらでも役に立ちません。

ただし、そのほとんどは、自分で CPU を設計している場合にのみ重要です。典型的なCPUを使用している場合、機能ユニットのゲートは十分に高速で実行されているため、1クロックサイクルで完全に追加できます. 最近のものの中には、1 つの機能ユニットでクロック サイクルごとに 2 つの加算を実行できるものもあります。

于 2011-06-01T20:56:39.540 に答える
1

どちらも単一の命令です。電子伝搬時間に関しては、どちらが速いかわかりません。

自分で速度をテストできると思いますが、違いはおそらく線形であり(検出可能であれば)、ノイズ要因の影響を受けるため、少し難しいかもしれません.

于 2011-06-01T19:41:29.397 に答える
1

ここでの最良の答えは、どちらが優れているかを予測しようとするのではなく、ベンチマークするか、アセンブリ コードをチェックすることです。どちらも同じ命令に最適化されると思いますが、いずれにせよ、両方が使用する CPU サイクル数は同じになる可能性があります。

ただし、ASM を確認し、両方のソリューションをベンチマークすることを強くお勧めします。

于 2011-06-01T19:41:52.097 に答える
0

|'+`は異なる数学演算です。
与えられた方程式:

  unsigned int y = 2 + 2;
  unsigned int z = 2 | 2;

異なる答えが得られます。

技術的には、 `| ' プロセッサ内でORゲートのみを使用するため、操作が高速になります。追加操作には、より多くのゲートが必要です。

'|'を使用することで得られるパフォーマンス '+'を超えると、通常、プロセッサにデータを出し入れするのに必要な時間が無駄になります。言い換えれば、正味のパフォーマンスはごくわずかです。(時間差は通常、ナノ秒の範囲です。)

ただし、2つのフォーム間のメンテナンス時間は長くなる可能性があります。ビットをいじるよりも算術が必要な場合(またはその逆)、このランタイムエラーを見つけようとするのは素晴らしいことです。

適切な目的のために適切な演算子を使用してください。テストグループとメンテナンスグループに休憩を与えます。この種のマイクロ最適化は価値がありません。

于 2011-06-01T19:51:19.250 に答える
0

これはプラットフォーム固有です (おそらくコンパイラ固有です)。私の記憶が正しければ、PS3 の SPU では、動的 OR は非常に高価です。数値はわかりませんが、複数の操作に分割することで結果的にコストが数命令に膨れ上がっているのではないかと思います。x86/x64 または最新の CISC では、いずれかが 1 つの命令である可能性が高く、パイプラインの停止やその他のコストのかかる操作が発生する可能性はほとんどありません。

編集: コストの理由は、Cell プロセッサには汎用レジスタが 1 つしかないためです。つまり、両方の変数を標準レジスタにロードして最適化を実行することはできません。代わりに、操作を実行する必要がある altivec レジスタ セットに値をロードする必要があります。結果を取得するには、結果をマスクによって altivec レジスタから gpr にフェッチする必要があります。

これらの操作を PS3 または最新のコンピューターの GPU にプッシュする場合は、それらのプロセッサの動作を調べる必要があるかもしれません。GPU も SIMD 操作専用の RISC プロセッサであるため、同様の問題が発生する可能性があります。

于 2011-06-01T21:33:19.240 に答える