2011-10-17 7 views
4

ブーストウルフ製品の性能を向上させる方法はありますか?ブーストuBLASマトリックス製品が極端に遅い

私は2つの行列Aを持って、私はmulitply /追加/サブしたいB/...

MATLABでC対++私は次の時間を取得[s]は2000×2000の行列演算のための

OPERATION | MATLAB | C++ (MSVC10) 
A + B  | 0.04 | 0.04 
A - B  | 0.04 | 0.04 
AB  | 1.0 | 62.66 
A'B'  | 1.0 | 54.35 

なぜこのような大きなパフォーマンスの低下がありますか?

マトリクスは実際の倍数に過ぎません。 しかし、私はまた、正定値、対称、長方形の製品が必要です。

EDIT: コードは自明である

matrix<double> A(2000 , 2000); 
// Fill Matrix A 
matrix<double> B = A; 

C = A + B; 
D = A - B; 
E = prod(A,B); 
F = prod(trans(A),trans(B)); 

EDIT 2: 結果は10 trysの平均値です。 STDDEVは、私は多分50にではなく、要因2-3を期待0.005未満

EDIT 3(!): すべてがリリース(NDEBUG/MOVE_SEMANTICS/..)モードでベンチました。

EDIT 4: プロダクト結果の事前割り当て済み行列はランタイムに影響しませんでした。

+0

きれいなMatlabを再実行してください。キャッシュする傾向があります。まあ、すべてです。まったく無関係ですが、まともなパフォーマンスを得ることができるはずです。[Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page)の簡単な構文です。 (私はそれがあなたの小さなベンチマークにどのように関係しているか興味を持っています:-) – rubenvb

+2

私は乗算と加算のために2000倍の時間を期待しています。 – ruslik

+2

uBlasのリリースモードをオンにすることを覚えましたか? [link = http://www.boost.org/doc/libs/1_47_0/libs/numeric/ublas/doc/index.htm]の最後にある[よくある質問]を参照してください。 '-DNDEBUG'や他のいくつかのフラグを使用して、リリース用にコンパイルすることができます。 –

答えて

4

可能性のある最適化に関するアドバイスについては、C + +コードを投稿してください。

ただし、Matlabは設計されたタスクに特化しており、Boostを使用してMatlabとマッチングさせることはできません。一方、Boostは無料ですが、Matlabは明らかにそうではありません。

uBlasコードを基礎となるLAPACK実装にバインドすることで、最高のブースト性能が得られると信じています。

+4

+1 "*基礎となるLAPACK実装にuBlasコードをバインドすることで、最高のBoost性能が得られると信じています。*"これは本当の答えです。 – ildjarn

0

ここでは、メモリ管理がどのような役割を果たしているのかわかりません。 prodは32MBの行列を割り当てなければならず、transも2回割り当てられているので、そのすべてを10回実行しています。いくつかstackhotsを取って、実際にが何をしているかを見てください。あなたがより良い結果を得るために行列をあらかじめ割り振っていれば、私の推測は間違いありません。マトリックス乗算を高速化することができ

他の方法は、キャッシュに優しい、そしてゼロをスキップ

  • であるためには、左側の行列を

    • を事前に移調されています。 A(i、k)およびB(k、j)が両方とも非ゼロである場合のみ、寄与する任意の値である。

    これがuBlasで行われるかどうかは、誰でも推測できます。

  • +0

    私は、これを避けるために(あるいは少なくとも仮定されている)式テンプレートを使用して、昇格することがかなり確信しています。 – user786653

    1

    ATLAS、gotoBLAS、MKLのような効率的なBLAS実装が多くありますが、代わりにそれらを使用します。

    私はコードを選ぶのではなく、3ループ、ブロックなし、そしてキャッシュフレンドリーではない、ublas :: prod(A、B)を推測します。それが本当であれば、prod(A、B.trans())は他のものよりはるかに速くなります。

    cblasを使用できる場合は、cblas_dgemmを使用して計算します。そうでなければ、代わりにデータ、手段、prod(A、B.trans())を単に並べ替えることができます。

    2

    不必要なコピーを取り除くには、マトリックス乗算の左側にnoaliasを使用する必要があります。

    代わり E = prod(A,B);使用の

    noalias(E) = prod(A,b);

    ドキュメントから:

    あなたは左側の発現と右手 式は共通のストレージを持っていないことを確認するために知っている場合は、その割り当てはエイリアシングを持っていません。 この場合、より効率的な割り当てを指定できます。noalias(C)= prod(A、B);通常の割り当てでは が必要な一時的なマトリックスが作成されないようにします。 'noalias'の割り当てでは、左側と右側のサイズが一致するように が必要です。

    関連する問題