(例: ポインタ/アドレスの変換にかかる CPU サイクル数)
ほとんどの機械語言語では、ポインターの「型」は 1 つしかないため、それらの間の変換に費用はかかりません。C++ 型は実際にはコンパイル時にのみ存在することに注意してください。
本当の問題は、この種のコードが厳密なエイリアシング ルールに違反する可能性があることです。これについては別の場所で詳しく読むことができますが、基本的に、コンパイラは未定義の動作によって誤ったコードを生成するか、保守的な仮定を強いられて低速なコードを生成します。char*
( and friends は、未定義の動作部分から多少免除されていることに注意してください)
オプティマイザーは、多くの場合、ポインターの存在下で変数について保守的な仮定を行う必要があります。たとえば、変数 x の値が 5 であることを知っている定数伝播プロセスは、別の変数 (たとえば、*y = 10) への代入後にこの情報を使用し続けることができません。これは、*y が別名である可能性があるためです。 xの。これは、y = &x のような代入の後に発生する可能性があります。
*y への代入の影響として、x の値も変更されるため、x が 5 であるという情報を *y = 10 に続くステートメントに伝搬すると、間違っている可能性があります (*y が実際に x のエイリアスである場合)。 )。ただし、ポインターに関する情報がある場合、定数伝播プロセスは次のようなクエリを作成できます。次に、答えがノーの場合、x = 5 は安全に伝播できます。エイリアシングによって影響を受けるもう 1 つの最適化は、コードの並べ替えです。x が *y によってエイリアス化されていないとコンパイラが判断した場合、x の値を使用または変更するコードは、割り当て *y = 10 の前に移動できます。これにより、スケジューリングが改善されるか、より多くのループ最適化を実行できるようになります。
このような最適化を予測可能な方法で有効にするために、C プログラミング言語 (新しい C99 版を含む。セクション 6.5、パラグラフ 7 を参照) の ISO 標準では、異なる型のポインターが同じものを参照することは (いくつかの例外を除いて) 違法であると規定しています。メモリの場所。「厳密なエイリアシング」として知られるこの規則により、パフォーマンスが大幅に向上する場合があります[1]が、そうでなければ有効なコードを壊してしまうことが知られています。いくつかのソフトウェア プロジェクトは、C99 標準のこの部分に意図的に違反しています。たとえば、Python 2.x は参照カウントを実装するためにそうしました[2]。この最適化を可能にするために、Python 3 の基本的なオブジェクト構造体に変更を加える必要がありました。Linux カーネルがこれを行うのは、厳密なエイリアシングがインライン コードの最適化で問題を引き起こすためです。[3] そのような場合、gcc でコンパイルすると、オプション -fno-strict-aliasing は、予期しないコードを生成する可能性のある望ましくない最適化を防ぐために呼び出されます。[編集]
http://en.wikipedia.org/wiki/Aliasing_(computing)#Conflicts_with_optimization
厳密なエイリアシング規則とは何ですか?