2016-09-27 49 views
1

ライブラリEigenを使用して、線形代数計算を行います。特に、私はランダムなベクトルにランダムな行列を掛けたいと思っています。ここで私が使用していたコードされていますベクトル行列の固有値との乗算

#include <iostream> 
#include <chrono> 
#include <Eigen/Dense> 

using namespace Eigen; 

int main(){ 

    Eigen::initParallel(); 
    Matrix<unsigned int,Dynamic,Dynamic> A; A = Matrix<unsigned int,500,15500>::Random(); 
    Matrix<unsigned int,Dynamic, Dynamic> s; s= Matrix<unsigned int,1,500>::Random(); 
    Matrix<unsigned int,Dynamic,Dynamic> b; 

    auto t1 = std::chrono::high_resolution_clock::now(); 

    b=s*A; 

    auto t2 = std::chrono::high_resolution_clock::now(); 
    auto timeMult = std::chrono::duration_cast <std::chrono::microseconds>(t2 - t1).count(); 
    std::cout << "Result size: " << b.rows() << "x" << b.cols() << std::endl; 
    std::cout << "Time for multiplication: " << timeMult << " microseconds" << std::endl; 

    return 0; 
} 

を次に、それをコンパイルするために、私は

g++ -I. -Wall -std=c++0x -fopenmp main.cpp 

を行うには、私はすべてが正常に動作信じている(私は、実際の結果を確認していない)が、それは本当に遅いようです。アイデアを得るために、私はC++というコードを書いてまったく同じことを行い、明示的にthreadを使用します。これは、上に貼り付けたコードより約54倍高速です!特に私のマシンでは、C++コードで5300マイクロ秒に対して286904マイクロ秒です。

なぜそれが遅いのか、それをより速くする方法についてのアイデアはありますか?

私はそれがはるかに大きいソフトウェアの一部であるため、私が書いたコードを掲載し、多くの作業を必要とするそれからMWEをしていないのです

EDIT。代わりに、私はそれが何をするかを記述しようとしています:std::vectorをラップするベクトルと行列のクラスを定義し、次に特定の数のthreadを定義する乗算を行い、塊で行列を分割して、それぞれthreadが線形結合ベクトル内の係数に従って行のうちの1つを選択する。各threadは、その部分結果を別の行ベクトルに書き込み、最後にすべてのベクトルを合計して最終結果を得ます。非常に簡単です。ちなみに、私は4 threadを使用していますが、この値は最適化されています。

+2

コンパイルコマンドに '-O2'または' -O3'を追加します。 –

+0

@AviGinsburgありがとう!私はこれを忘れてしまったのはかなり恥ずかしいです...とにかく '-O2'、' -O3'、あるいは '-Ofast'の時間は21500マイクロ秒を下回らず、これは私のコードよりも4倍遅いです! – minomic

+0

あなたが比較しているコードを投稿してください。 –

答えて

2

さらに(コメントで指摘したように)あなたのコンパイルフラグに-O2または-O3を追加するには、[Matrix<unsigned int,1,Dynamic>sbの種類を変更する必要があります。 Eigenがコンパイル時に、製品の要素の1つがベクトルであることが分かっている場合は、はるかに高速な製品実装を使用できます。 私のマシンで実行時間を25392μsから4751μsに変更しました。

しかし、現時点ではマトリックスベクトル製品(Eigen 3.3rc1)のマルチスレッド化のメリットはありません。

+0

素晴らしいアイデア!私は、実行時間が現在、C++コードとまったく同じ5300マイクロ秒であることを確認します。 – minomic

+1

Eigen 3.3では、AVXのスピードアップを得るために '-march = native'を忘れないでください。 – ggael

関連する問題