2

次のパフォーマンスを比較するためにかなり単純なタスクを実行しているときに、不可解な結果が得られます。

  • 固有値::行列
  • boost::multi_array
  • boost::multi_array は、Eigen::Map を使用して Eigen::Matrix にマップされます

これは私のテスト コードの要約版です。完全版はhttp://pastebin.com/faZ7TvJGにあります。

boost::multi_array<double, 2, Eigen::aligned_allocator<double> > boost_multi_array;
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> eigen_matrix;
Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> > boost_multi_array_mapped(boost_multi_array.data(), rows, cols);

double
    tmp_sum = 0,
    tmp_time = omp_get_wtime();

for(size_t i=0; i<iterations; i++)
{
    for(size_t j=0; j<rows; j++)
    {
        for(size_t k=0; k<cols; k++)
        {
            //if(k%2==0)
            //{ // commented out are the different options
                //tmp_sum += boost_multi_array[j][k];
                //tmp_sum += boost_multi_array_mapped(j,k);
                tmp_sum += eigen_matrix(j,k);
            //}
        }
    }
}

const double sequential_access_time = omp_get_wtime() - tmp_time;

結果は次のとおりです。

Sequential Access:
   BOOST (MAPPED)   : 1.45763s
   EIGEN            : 1.45736s
   BOOST            : 2.58971s

if ステートメントを使用して 1 つおきの要素をスキップすると、次の結果が得られます。

Alternating Access:
   BOOST (MAPPED)   : 1.67301s
   EIGEN            : 2.08834s
   BOOST            : 2.35295s

アセンブリを調べると、シーケンシャル アクセスの場合は合計がベクトル化されるため Eigen の方が高速ですが、生の boost::multi_array を使用する場合はそうではありません。

私の質問は次のとおりです。

  1. Eigen::Matrix がベクトル化されているのに、boost::multi_array がベクトル化されないのはなぜですか?
  2. Eigen にマップされた multi_array が「ネイティブ」Eigen データ構造よりも速いのはなぜですか?

コンパイルには、次を使用します。

g++ -I /usr/include/eigen3 test.cpp -Wall -O3 -DNDEBUG -DBOOST_DISABLE_ASSERTS -fopenmp -ffast-math -funroll-loops -march=native -mtune=native -o array_test

回答ありがとうございます。

4

0 に答える 0