2016年11月16日水曜日

Expression templates 2

スカラとベクトル、スカラと行列については実装の目途が立ってきた。

ベクトルと行列に関しては、設計を煮詰める必要性があるようだ。
Eigen みたいにスカラもベクトルも行列もすべて行列として扱うのが合理的なんだろうな。

話は変わってテストケースを追加している際に、最適化(-O2)を有効にすると segfault で
vc14 / g++ / clang で全滅に遭遇した。
下記のようなケースが一例。

    auto exp = (va + vb) + (vc + vd);
    vector v(exp);

expression をコンストラクタに渡すと中でお亡くなりになっているようだった。
単純なケースでは発生しなかったので、expression が複雑になると何かが起きているようだ。

template<L, Op, R>   
class expression
{
public:
    expression(const L& l, const R& r) : l_(l), r_(r) {}
    // ...
private:
    const L& l_;
    const R& e_;
}    

上記は ETs(Expression templates) のサンプルに頻繁に記載されているような
単純な expression クラステンプレート。

const reference から猛烈な激臭がしてくる。

    expression exp_temp1 = va + vb;
    expression exp_temp2 = vc + vd;
    expression exp = exp_temp1 + exp_temp2;
    vector v(exp);

と考えると、最適化の影響で一時変数が消されている可能性が高い。
行きつく先は dangling reference となる。

というわけで const reference となっている箇所をスカラと expression については
実体としてもつようにすると案の定というか必然というか問題は解消した。
※ 併せてスカラ(ラッパー)内の const reference も実体としてもつように


vc14 の release build の結果.

0 件のコメント :

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。