0

基本的に、配列のすべての要素に定数を追加するコードがあります

Matrix a.array() += 32768; //Bad due to hard coded literal

行列のスカラー型はunsigned short intです。私が検討している他のいくつかのオプションは次のとおりです。

Matrix a.array() += std::numeric_limits<Matrix::Scalar>::max()/2 + 1;

Matrix a.array() += (std::numeric_limits<Matrix::Scalar>::max() >> 1) + 1;

2 番目の解決策は私には最も読みやすいように見えますが、1 番目のオプションと比較してペナルティを支払う必要があります。コンパイル時にこれを事前計算する標準コンパイラはありますか?

現在 gcc 4.6.3 を使用していますが、古いコードに依存しているため、C++11 は使用していません。

アップデート:

アセンブリ出力に関する私の限られた知識から、コンパイラはそれを最適化していないと言います。-std=c++0x フラグを付けても話は同じです。

アセンブリ出力は次のとおりです。

-std=c++0x フラグを指定して方法 2 を使用する

ハードコーディングされたリテラル(26 行目を参照)

Update2

-O2 フラグを使用すると、-std=c++0x フラグを使用するかどうかに関係なく、同一のアセンブリ ファイルが生成されます。

結論

-O2 などの最適化フラグが適切に機能するため、おそらく Method2 がベスト プラクティスです。また、これらのコードはクラス メンバー メソッドの一部になっているため、初期化されたプライベート const 変数を使用することになりました。std::numeric_limits<MyMatrix::Scalar>::max()/2 + 1

4

1 に答える 1

1

以前は、何かを as として宣言しconst、誰かがその ness をオーバーライドできconstたので、コンパイラがコードを最適化していない可能性がありました。C++11constexprでは、「はい、これは定数であり、コンパイル時に使用できます」という宣言を行うことができます。これが意味することは、引数をconstexpr持つ関数constexprはコンパイル時に評価できるということです。

では、これはあなたの特定のケースではどういう意味ですか? C++11 を使用している場合 (これを強くお勧めします)、関数std::numeric_limits<unsigned short int>::max()が として宣言されているconstexprため、コンパイル時に最適化されます。

通常、c++11 を有効にするのは、コンパイラ フラグを設定するのと同じくらい簡単です。

于 2014-04-01T03:44:51.613 に答える