1

検索しても答えが見つからなかったので、次のステップは質問です。次のようなコードがあるとします。

template<class Int>
inline Int onbit(Int value, int n) {
  return value | (static_cast<Int>(1) << n);
}

このようにコードを呼び出すonbit(A, 4)と、定数4が伝播されて最適化されますか、それとも定数になるtemplate<int n, class Int>ようにテンプレート()にする必要があります。ここではC++0x constexprが必要ですか?必要な場合は、どの程度正確に使用する必要がありますか(int nconstまたはconstexprである必要がありますか?)。

constexprは定数パラメーターで機能することを知っていますが、パラメーターの一部が一定で一部が可変である場合、部分的に最適化されますか?

要約:関数(インラインで正しくなければならない)を定数伝播で部分的に最適化することは可能ですか?もしそうなら、それを行うための要件は何ですか?

これを書いているときでさえ、インライン関数呼び出しが定数を伝播すると思っています...

4

3 に答える 3

4

すべてのコンパイラがこのコードを最適化することを保証することはできませんが、ほとんどの最新のコンパイラ(MSVCおよびgcc)は、関数が非常に単純であるため、少なくともほとんどの場合(コンテキストに依存します)、定数に関係なく最適化します。

一方、 constを使用する場合コンパイラが厳密に最適化することを保証することはできません。

したがって、最適化が重要である場合、すべての場合において唯一の答えは、重要な場合にアセンブリをチェックすることです。コンパイラは1つのファイルで最適化できますが、他のファイルでは最適化できません(たとえば、この関数が複雑なテンプレートの奥深くで呼び出された場合、コンパイラのオプティマイザが諦めて最適化しない場合もあります)。

コンパイル時のチェックに必要な場合にのみconstに依存する必要があり、実行時の効率に必要な場合に生成されたアセンブリのチェックに依存する必要があると思います。

于 2011-08-01T17:15:25.337 に答える
1

最も可能性の高いシナリオでは、はい、コードを指定した形式でもOnbit(A、4)を呼び出している場所で実行する必要があります。ただし、ここでも、コンパイラーがそれを実行することを期待できます。最適化が行われることを確信できる方法はありません。標準では、コンパイラの実装に任せて、希望どおりに実行します。

于 2011-08-01T16:58:54.247 に答える
-3

「定数伝播」を強制するには、テンプレート引数にintnを追加する必要があります。テンプレート引数として異なるnを使用してonbit()を呼び出すすべての場所に対して、新しいマシンコードを生成することを覚えておいてください(定数を伝播した場合、これはあなたが生きなければならないものだと思います)。

関数をテンプレート化することは、コンパイラーがそれをインライン化することを意味しません。テンプレートから生成されたコードをインライン化するのはコンパイラーの責任です(コンパイラーよりもよく考えていることが確実な場合は、コンパイラー固有の拡張機能を使用してオーバーライドできるはずです)。

ただし、定数の伝播とインライン展開の組み合わせを適用することを検討している場合は、マクロを使用することをお勧めします。C / C ++には、1つのクロスプラットフォームの方法でインライン化と定数伝​​播の組み合わせを実現できるものは他にありません。

#define ON_BIT(v,n) ((v) | 1 << (n))

または同様のもの。マクロを使用するのは悪いことだと私は知っています...しかし、あなたはとにかく悪い子だと思います。時期尚早の最適化について考えています:)。

于 2011-08-01T17:17:18.380 に答える