6

"ans = n * 3" または "ans = n+(n*2)" のどちらが高速なコードにコンパイルされますか?

n が int または long のいずれかであり、最新の Win32 Intel ボックスで実行されていると仮定します。

逆参照が含まれている場合、これは異なるでしょうか。つまり、どちらが高速でしょうか?

長い;
長い *pn;
長文;

...
*pn = some_number;
ans = *pn * 3;

または

ans = *pn+(*pn*2);

それとも、最適化コンパイラがいずれにしてもこれを説明する可能性が高いため、心配する必要はありませんか?

4

11 に答える 11

55

特殊なコンパイラを使用しない限り、IMO のようなマイクロ最適化は必要ありません。そもそも読みやすさを優先します。

于 2008-09-10T10:48:08.657 に答える
15

それは問題ではありません。最新のプロセッサは、整数 MUL 命令を 1 クロック サイクル以下で実行できます。これは、MUL を実行するために一連のシフトと加算を実行する必要があった古いプロセッサとは異なり、複数のサイクルを使用します。私はそれを賭けるだろう

MUL EAX,3

よりも速く実行されます

MOV EBX,EAX
SHL EAX,1
ADD EAX,EBX

この種の最適化が有効だった可能性がある最後のプロセッサは、おそらく 486 でした (はい、これは Intel プロセッサに偏っていますが、おそらく他のアーキテクチャの代表でもあります)。

いずれにせよ、妥当なコンパイラであれば、最小/最速のコードを生成できるはずです。したがって、常に読みやすさを第一に考えてください。

于 2008-09-10T11:30:46.883 に答える
10

自分で測るのは簡単なのでやってみませんか?( cygwinを使用gccして)time

/* test1.c */
int main()
{
    int result = 0;
    int times = 1000000000;
    while (--times)
        result = result * 3;
    return result;
}

machine:~$ gcc -O2 test1.c -o test1
machine:~$ time ./test1.exe

real    0m0.673s
user    0m0.608s
sys     0m0.000s

数回テストを行い、他のケースで繰り返します。

アセンブリコードをのぞきたい場合は、gcc -S -O2 test1.c

于 2008-09-10T11:06:09.783 に答える
4

これは、コンパイラ、その構成、および周囲のコードによって異なります。

測定を行わずに物事が「速い」かどうかを推測しようとするべきではありません。

一般に、最近ではこの種のナノスケールの最適化について心配する必要はありません。ほとんどの場合、完全に無関係であり、それが重要なドメインで本当に作業している場合は、すでにプロファイラーを使用してアセンブリ言語の出力を見ているでしょう。コンパイラ。

于 2008-09-10T10:51:54.997 に答える
4

コンパイラがコードで何をしているのかを知ることは難しくありません (ここでは DevStudio 2005 を使用しています)。次のコードで簡単なプログラムを作成します。

int i = 45, j, k;
j = i * 3;
k = i + (i * 2);

中間行にブレークポイントを配置し、デバッガーを使用してコードを実行します。ブレークポイントがトリガーされたら、ソース ファイルを右クリックし、[Go To Disassembly] を選択します。CPU が実行しているコードを含むウィンドウが表示されます。この場合、最後の 2 行がまったく同じ命令、つまり "lea eax,[ebx+ebx*2]" (この特定のケースではビット シフトと加算ではない) を生成することに気付くでしょう。最新の IA32 CPU では、CPU のパイプライン処理の性質により、変更された値をすぐに使用するとペナルティが発生するため、ビット シフトよりもストレート MUL を実行する方がおそらく効率的です。

これは、aku が何を話しているかを示しています。つまり、コンパイラは、コードに最適な命令を選択するのに十分賢いということです。

于 2008-09-10T11:45:10.390 に答える
1

気にしない。最適化することがもっと重要だと思います。自分でコーディングしてテストするのではなく、その質問を考えて書くことにどれだけの時間を費やしましたか?

:-)

于 2008-11-20T01:00:08.093 に答える
1

適切な最適化コンパイラを使用している限り、コンパイラが理解しやすいコードを記述してください。これにより、コンパイラーは巧妙な最適化を簡単に実行できます。

この質問をすることは、最適化コンパイラがあなたよりも最適化についてよく知っていることを示しています。したがって、コンパイラを信頼してください。を使用しn * 3ます。

この答えも見てください。

于 2008-11-20T01:15:05.770 に答える
1

実際に使用しているコンパイラによって異なりますが、おそらく同じコードに変換されます。

小さなテスト プログラムを作成し、その逆アセンブルを確認することで、自分で確認できます。

于 2008-09-10T10:48:40.463 に答える
1

ほとんどのコンパイラは、整数の乗算を一連のビット シフトと加算に分解するほどスマートです。Windows コンパイラについてはわかりませんが、少なくとも gcc ではアセンブラを吐き出すことができます。

于 2008-09-10T10:49:33.473 に答える
0

そのような小さなコードを最適化するコンパイラを信頼してください。コードレベルでは、可読性がはるかに重要です。真の最適化は、より高いレベルで実現する必要があります。

于 2008-09-15T14:09:43.887 に答える
0

コンパイラは、あなたのようなコードを最適化するのが得意です。最新のコンパイラは、両方のケースで同じコードを生成し、さらに* 2左シフトで置き換えます。

于 2008-09-10T10:50:38.057 に答える