5

ScottMeyersによるEffectiveC++から:

template<typename T, std::size_t n>
class SquareMatrix: private SquareMatrixBase<T> {

public:

    SquareMatrix( ) 
     : SquareMatrixBase<T>(n, 0), 
       pData(new T[n*n]) 
    {
         this->setDataPtr(pData.get()); 
    } 

        ...
private:

    boost::scoped_array<T> pData;
};

データが格納されている場所に関係なく、肥大化の観点からの重要な結果は、SquareMatrixのメンバー関数の多く(おそらくすべて)が、同じタイプを保持する他のすべてのマトリックスと共有される基本クラスバージョンへの単純なインライン呼び出しである可能性があることです。サイズに関係なく、データ。同時に、異なるサイズのSquareMatrixオブジェクトは異なるタイプであるため、たとえば、SquareMatrix <double、5>オブジェクトとSquareMatrix <double、1 0>オブジェクトは、SquareMatrixBase <double>で同じメンバー関数を使用しますが、 SquareMatrix <double、5>オブジェクトをSquareMatrix <double、10>を期待する関数に渡します。いいですね

いいですね、はい、でも無料ではありません。マトリックスサイズが組み込まれたinvertのバージョンは、サイズが関数パラメーターとして渡されるか、オブジェクトに格納される共有バージョンよりも優れたコードを生成する可能性があります。たとえば、サイズ固有のバージョンでは、サイズはコンパイル時の定数であるため、即値オペランドとして生成された命令に折りたたまれるなど、定数の伝播などの最適化に適しています。サイズに依存しないバージョンでは、これを行うことはできません。

上記の最後の段落の説明では、「したがって、定数オペランドとして生成された命令に折りたたまれることを含む、定数伝搬などの最適化に適格である」と述べられています。このステートメントはどういう意味ですか?説明をお願いします。

ありがとう!

4

2 に答える 2

10

定数伝搬は、コンパイラーに任された非常に単純な(原則として)最適化です。

size_t radius = 5;
size_t diameter = 2*radius;
float perimeter = diameter * 3.1416f;

これは、定数を伝搬することによってコンパイラーによって削減されます。

  • radiusの値がわかっていることに注意してください
  • の計算を実行します2*radius(これは定数畳み込みです)
  • diameterしたがって、の値は既知です
  • の計算を実行しますdiameter * 3.1416f
  • perimeterしたがって、の値は既知です

したがって、このプログラムは次のようになります。

size_t radius = 5;
size_t diameter = 10;
float perimeter = 31.416f;

最適化には他にも多くの形式があることに注意してください。たとえば、radiusdiameter不要になった場合は、それらを削除して、を保持するだけで済みperimeterます。

于 2011-02-08T15:41:19.447 に答える
0

次のような元のコードがある場合:

a:=3;
b:=4;
b+=1;
b+=2;
a:=a+b;

次に、ステートメントはコンパイラーによって次のように最適化できます。

b==7;
a==10;

これは、定数伝播と定数畳み込みと呼ばれます。

于 2015-05-31T03:49:47.577 に答える