CまたはC ++コードでconst-correctnessを適用することは、保守性に関して良い習慣であるだけでなく、コンパイラーが最適化を実行できるようになる可能性があることを何度も読みました。しかし、私も完全に反対のことを読みました—それはパフォーマンスにまったく影響を与えないということです。
したがって、constの正当性がコンパイラーのプログラムのパフォーマンス向上に役立つ可能性がある例はありますか?
CまたはC ++コードでconst-correctnessを適用することは、保守性に関して良い習慣であるだけでなく、コンパイラーが最適化を実行できるようになる可能性があることを何度も読みました。しかし、私も完全に反対のことを読みました—それはパフォーマンスにまったく影響を与えないということです。
したがって、constの正当性がコンパイラーのプログラムのパフォーマンス向上に役立つ可能性がある例はありますか?
const
パフォーマンスに違いが生じた例を次に示します:stackoverflow.com/questions/1121791/…。ただし、これは本質的に実装の品質の問題でした。const
コンパイラーが合法的に最適化を行うことができるかどうかを判断しませんでした。コンパイラーのバージョンが欠落しているときに、それを行うことができなかっただけです。
回答:
const
const_cast
とmutable
は言語であるため、正確さによってパフォーマンスを向上させることはできず、コードが規則に準拠して違反する可能性があります。これはC ++ 11ではさらに悪化します。const
たとえば、データがへのポインタである可能性があるためstd::atomic
、コンパイラは他のスレッドによって行われた変更を尊重する必要があります。
とは言うものの、コンパイラーが生成するコードを調べて、実際に特定の変数に書き込むかどうかを判断し、それに応じて最適化を適用するのは簡単です。
とはconst
いえ、正しさは良いことです、保守性に関してことです。そうしないと、クラスのクライアントがそのクラスの内部メンバーを壊す可能性があります。たとえば、標準について考えてstd::string::c_str()
みましょう。const値を返すことができなかった場合は、文字列の内部バッファをいじくり回すことができます。
const
パフォーマンス上の理由から使用しないでください。保守性の理由で使用してください。
const
は、「あなたは愚かなことをしている」という道標です。
はい、できます。
ほとんどconst
のsは純粋にプログラマーの利益のためであり、それらをキャストすることは合法であり、コンパイラーに最適化に役立つことを何も伝えないため、コンパイラーの最適化には役立ちません。ただし、一部はconst
(合法的に)キャストできず、これらはコンパイラーに最適化に役立つ情報を提供します。
例として、const
型で定義されたグローバル変数へのアクセスはインライン化できますが、const
型のないグローバル変数は実行時に変更される可能性があるため、インライン化できません。
C ++:
int foo1 = 1;
const int foo2 = 2;
int get_foo1() {
return foo1;
}
int get_foo2() {
return foo2;
}
asm:
foo1:
.long 1
foo2:
.long 2
get_foo1():
push rbp
mov rbp, rsp
mov eax, DWORD PTR foo1[rip] ; foo1 must be accessed by address
pop rbp
ret
get_foo2():
push rbp
mov rbp, rsp
mov eax, 2 ; foo2 has been replaced with an immediate 2
pop rbp
ret
実際には、const
パフォーマンスは向上しますが、ほとんどの場合、向上しないか、向上しますが、変化は目立たないことに注意してください。の主な有用性const
は最適化ではありません。
Steve Jessopは、最初の質問に対するコメントで、言及する価値のある何かをもたらす別の例を示しています。ブロックスコープでは、コンパイラconst
は変数のすべての使用を確認できるため、に関係なく、変数が変更されるかどうかを推測し、それに応じて最適化することができます。対照的に、上記の例ではfoo1
、他の翻訳単位で変更される可能性があるため、変更されるかどうかを予測することはできません。架空の知覚力のあるウルトラコンパイラーは、プログラム全体を分析して、インラインアクセスが有効かどうかを判断できると思いfoo1
ますが、実際のコンパイラーはできません。
私の経験では、
スカラー変数の場合、コンパイラーは値が変更されるたびに判別し、必要な最適化を実行できます。
配列ポインターの場合、constの正確性は、潜在的なエイリアシングの問題が存在する場合に値が実際に一定であることを保証するものではありません。したがって、コンパイラーはconst修飾子のみを使用して最適化を実行することはできません。
最適化を検討している__restrict__
場合は、特別な関数修飾子/属性を検討する必要があります:http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
少し古いですが、まだ適用されます:http://www.gotw.ca/gotw/081.htm その他:http://cpp-next.com/archive/2009/08/want-speed-pass-by -値/