0

これらの比較操作の多くを実行しているコードがあります。どれを使うのが最も効率的かを考えていました。意図的に「間違った」ものを選択した場合、コンパイラがそれを修正する可能性はありますか?

int a, b;
// Assign a value to a and b.

// Now check whether either is zero.

// The worst?
if (a * b == 0)       // ...
// The best?
if (a & b == 0)       // ...
// The most obvious?
if (a == 0 || b == 0) // ...

他のアイデア?

4

6 に答える 6

0

「効率」がコンパイルされたコードの効率を意味する場合、「Cでそれを行う最も効率的な方法」はありません。

まず、コンパイラが C 言語の演算子を「明白な」機械の対応するものに変換すると仮定しても (つまり、C の乗算を機械の乗算に変換するなど)、各方法の効率はハードウェア プラットフォームごとに異なります。非常に特定のハードウェア プラットフォーム上の非常に特定の命令シーケンスに検討を限定したとしても、たとえば、全体が分岐予測ヒューリスティックとどれだけ一致するかによって、さまざまな周囲のコンテキストで異なるパフォーマンスを示す可能性があります。指定された CPU。

第 2 に、最新の C コンパイラは、C 演算子を「明白な」マシンの対応物に変換することはめったにありません。多くの場合、マシン コードで使用される命令は、C コードとほとんど共通点がありません。Cレベルでチェックを実行する多くの「完全に異なる」方法が、実際にはスマートコンパイラによって同じマシン命令シーケンスに変換される可能性があります。同時に、周囲のコンテキストが異なる場合、同じ C コードが異なるシーケンスの機械語命令に変換される可能性があります。

つまり、特定のハードウェア プラットフォーム、特定のコンパイラ バージョン、および特定のコンパイル設定セットに実際にローカライズしない限り、あなたの質問に対する意味のある答えはありません。そして、ローカライズされすぎて役に立たなくなります。

これは通常、最も読みやすいコードを書くことが最善の方法であることを意味します。やるだけ

if (a == 0 || b == 0)

コードの読みやすさは、人間の読者がそれを理解するのに役立つだけでなく、コンパイラが意図を適切に解釈して最適なコードを生成する可能性を高めます。

しかし、パフォーマンスが重要なコードから最後の CPU サイクルを絞り出す必要がある場合は、さまざまなバージョンを試して、それらの相対的な効率を手動で比較する必要があります。

于 2013-09-08T17:18:38.453 に答える
0

1 つの比較命令を使用して、2 つの整数のいずれかがゼロかどうかを調べたい場合...

if ((a << b) == a)

aがゼロの場合、左にシフトしても値は変わりません。

bがゼロの場合、シフトは実行されません。

bが負または非常に大きい場合、未定義の動作が発生する可能性があります (チェックするのが面倒です) 。

ただし、直感的でないため、これをマクロとして (適切なコメントを付けて) 実装することを強くお勧めします。

お役に立てれば。

于 2013-09-08T16:56:11.323 に答える
0

効率によってプログラマーの時間を測定している場合、最も効率的であることは確かに最も明白です。

プロセッサの時間を使用して効率を測定することによって、候補のソリューションをプロファイリングすることが、プロファイリングしたターゲット マシンに対する最良の回答方法です。

しかし、この演習では、プログラマーの最適化の落とし穴を示しました。3 つの候補は、すべての に対して機能的に同等というわけではありませんint


あなたが機能的に同等の代替案だった場合...
最後の候補と4番目の候補は比較に値すると思います。

if ((a == 0) || (b == 0))
if ((a == 0) |  (b == 0))

コンパイラ、最適化、CPU 分岐予測の違いにより、相対的なパフォーマンスを判断するには、正当化するのではなく、プロファイルを作成する必要があります。OTOH、優れた最適化コンパイラは、両方に対して同じコードを提供する場合があります。

保守が最も簡単なコードをお勧めします。

于 2013-09-08T16:56:20.267 に答える
0

これがアプリの全体的なパフォーマンスに大きな影響を与える可能性はほとんどありません (最新のコンパイラ オプティマイザーを考えると)。本当に知る必要がある場合は、コンパイラのそれぞれのパフォーマンスをテストするコードを作成する必要があります。しかし、最良の推測として、私は言うでしょう...

if ( !( a && b ) )

最初の値が 0 の場合、これは短絡します。

于 2013-09-08T14:14:34.217 に答える