ページ 11

[C++]テンプレートいろいろ

Posted: 2014年6月03日(火) 23:29
by ただの屍のようだ
その1:テンプレートの宣言と定義のファイル分けについて:これでコンパイル依存度を減らせたのでしょうか?

コード:

//宣言ヘッダー
#include 実装ヘッダー
namespace MY_TEST_TMP_HEADER{
int factorial(int n);
template<unsigned n> struct Factorial;
template<> struct Factorial<0>;
}

コード:

//実装ヘッダー
namespace MY_TEST_TMP_HEADER{
int factorial(int n){
	int value = 0;
	while(n)
		value += n--;
	return value;
}
template<unsigned n>
struct Factorial{
	enum {value = n + Factorial<n-1>::value};
};
template<>
struct Factorial<0>{
	enum {value = 0};
};
}
その2:通常関数とTMP再帰について:
個人的にはコンパイル時間:factorial < sturct Factorial ; 実行時間:factorial > sturct Factorial だと思いますが、どうでしょう?

コード:

//インクルードいろいろ+名前空間引用
int _tmain(int argc, _TCHAR* argv[])
{
	cout << factorial(5) << '\t';
	cout << factorial(10) << '\t';
	cout << Factorial<5>::value << '\t';
	cout << Factorial<10>::value << '\t';
	getchar();
	return 0;
}

Re: [C++]テンプレートいろいろ

Posted: 2014年6月03日(火) 23:56
by ただの屍のようだ
[補足]//書き忘れ
その3:struct Factorial と factorial に比べ、実行ファイルが大きくなる、キャッシュのヒット率が低くなる恐れがありますか?
*またつづり間違えました:sturct → struct (本人の英語力()が伺えますね、自覚はあるもののなかなか英語やる時間がひねり出せないです)

Re: [C++]テンプレートいろいろ

Posted: 2014年6月04日(水) 09:21
by h2so5
その1: 減ってません
その2: 測ってください
その3: テンプレートの方は定数なので一般的にはコードサイズは減ります、実行時に計算していないのでキャッシュヒット率は比較不可能

Re: [C++]テンプレートいろいろ

Posted: 2014年6月04日(水) 11:56
by ただの屍のようだ
返事ありがとございます。
その1:では、コンパイラ依存度が減るような、前方宣言と定義の分け方を教えて下さい。
*テンプレートはヘッダーに定義を書かないとコンパイル通らないということは一応知っていますが、externを使えば前方宣言可能といううわさも聞いています。

その2:解決です。

その3:通常関数であれば、呼び出し一回に対して、TMP再帰では構造体をnこもコンパイル時に具体化していると思います。どうなんでしょうか?
    キャッシュのヒット率はようするに: メモリを必要以上に使う→キャッシュの領域も大幅に使う→ほかの操作のヒット率を下げている と思っています。

>「 テンプレートは慎重に使わなければコードが膨れ上がってしまいます。それは、バイナリやデータがコピーされ、増えていくからです。
   その結果、コードがとてもスリムに見えても、オブジェクトファイルはファッショナブルではありません。                     
   →その対策として、ポインタを通してデータの格納されてあるクラスにアクセスし、インライン関数呼び出しなどによってコードの複製を
    ある程度減らすことができます。                                                                  」

Re: [C++]テンプレートいろいろ

Posted: 2014年6月04日(水) 14:56
by h2so5
ただの屍のようだ さんが書きました: その1:では、コンパイラ依存度が減るような、前方宣言と定義の分け方を教えて下さい。
*テンプレートはヘッダーに定義を書かないとコンパイル通らないということは一応知っていますが、externを使えば前方宣言可能といううわさも聞いています。
存在しません。
ただの屍のようだ さんが書きました: その3:通常関数であれば、呼び出し一回に対して、TMP再帰では構造体をnこもコンパイル時に具体化していると思います。どうなんでしょうか?
    キャッシュのヒット率はようするに: メモリを必要以上に使う→キャッシュの領域も大幅に使う→ほかの操作のヒット率を下げている と思っています。
コンパイル時に具体化していても、オブジェクトファイルに出力した時点で定数になるのでコードサイズは大きくなりません。
メインメモリの使用量とキャッシュメモリは関係ありません。

Re: [C++]テンプレートいろいろ

Posted: 2014年6月04日(水) 15:35
by ただの屍のようだ
その1:<iosfwd>ヘッダーで使われている技術、未熟な自分が中身を覗いてみても”どこがどうすごい?”としか思いませんでしたので
     自分でもわかるように解説してください。

その3: ソース→オブジェクトファイル までの処理は気になるものの、一応解決ということで。

その4: ← new  以下のコメントに対して説明お願いします。
> 「 インライン化には注意が必要です。オブジェクトコードが必要以上に大きくなれば、スペースが足りなくなってしまうかもしれません、
   仮想メモリを使用していても、膨らんだコードは余分なページングを引き起こし、キャッシュのヒット率を減らし、効率を落とすことに
   なるかもしれません                                                                   」

Re: [C++]テンプレートいろいろ

Posted: 2014年6月04日(水) 16:50
by h2so5
ただの屍のようだ さんが書きました:その1:<iosfwd>ヘッダーで使われている技術、未熟な自分が中身を覗いてみても”どこがどうすごい?”としか思いませんでしたので
     自分でもわかるように解説してください。
iosfwdで使っている前方宣言はFactorialには適用できないですよ。
前方宣言だけではFactorialのポインタや参照は使えてもvalueにアクセスできないですから。
ただの屍のようだ さんが書きました: その4: ← new  以下のコメントに対して説明お願いします。
> 「 インライン化には注意が必要です。オブジェクトコードが必要以上に大きくなれば、スペースが足りなくなってしまうかもしれません、
   仮想メモリを使用していても、膨らんだコードは余分なページングを引き起こし、キャッシュのヒット率を減らし、効率を落とすことに
   なるかもしれません                                                                   」
失礼、前の回答は質問の意味を勘違いしていました。確かにテンプレートを使用してコードサイズが増加した場合はキャッシュヒット率が低下する可能性があります。
ただし先ほど書いた通り、Fractionalの場合はコードサイズは増加しないのでキャッシュミスが増えるということはありません。

※以前も書いたのですが、文章を引用する場合は出典を明記してください。

Re: [C++]テンプレートいろいろ

Posted: 2014年6月04日(水) 17:34
by ただの屍のようだ
回答ありがとうございます。
その1:解決です
    ようするに前方宣言ヘッダーとポインタアクセスを合わせて使用することでコンパイラ依存性を取り除くことができるってことですね。

その4:解決です。やはりよい設計をするには、UMLの学習も必要不可欠のようですね。

それでは座学へ戻ります