0

実行命令の前のコンベア アーキテクチャでは、命令はより小さな命令に分割されます。したがって、それらははるかに高速に実行されます。ただし、命令全体を実行する前に、同じレジスタにアドレッシングされた次の命令を実行することはできません。そうですか、同じレジスタ (または RAM セル) にアピールする命令の順序を最適化するために、これらの命令は互いにできるだけ離れて配置されましたか? または、コンパイラ自体がこのように最適化するため、これには意味がありませんか?

例えば:

int a = 1, b = 2, c = 3;
a *= a;
b *= a;  // stop and waiting for the end of calculating (a)
c *= c;

最適化:

int a = 1, b = 2, c = 3;
a *= a;
c *= c;  // calculating (a), but we don't need this and don't stop
b *= a;
4

1 に答える 1

1

明らかに、コンパイラとアーキテクチャに依存します。最新の X86 プロセッサは、アウト オブ オーダー実行をサポートしています。これは、プロセッサが実際に命令を順番に実行する必要がないことを意味します。代わりに、いくつかの命令を先に読み (実際にはそれほど多くはありません)、実行前にパフォーマンスを向上させるためにそれらを並べ替えます。これは、実際の実行順序はコード内の命令の順序に依存しないため、この最適化は、アウト オブ オーダーの CPU には実際には必要ないことを意味します。

in order アーキテクチャ (Cell など) では、命令の順序が重要です。ただし、適切に最適化するコンパイラは、多くの場合、この並べ替えを自分で実行できる可能性が非常に高くなります (これが証明できる限り、これによってコードの動作が変更されることはありません)。volatileほとんどの場合、コンパイラーは異なるポインターが同じ変数を指していないことを証明できないため、これが失敗する可能性が高い主なシナリオは、ポインター (または変数) が含まれている場合です。そのような__restrict場合に役立つことがあります。

考慮すべきもう 1 つの点は、多くの場合、整数乗算などのレイテンシーがランタイムに実際に影響を与えないことです。これは、多くのプログラムのパフォーマンスがメモリー アクセスによって制限されるためです。違いが生じる場合は、simd やマルチスレッドを使用してコードを最適化することを検討してから、命令の配置を検討する方が役立つ場合があります。

結論として、この種の最適化はコンパイルされた言語ではあまり役に立たないと思います (アセンブリを記述する場合、状況は異なる可能性があります)。CPU とコンパイラの両方がとにかく順序を変更する可能性があり、違いさえない可能性があるためです。 . これは、この種の最適化が役立つ状況がないという意味ではありませんが、コンパイラ/CPU がタスクに対応していないことが証明されている場合、それは実際には最も重要なコード パスでのみ有効です。

于 2012-09-26T15:02:28.160 に答える