0

makemake Boost Ublas Matrix の要素ごとの製品のデフォルト関数のベンチマークを行ったところ、単純な for ループを使用して独自の実装を作成した場合よりも element_prod の方がはるかに遅いことがわかりました。それで、私は自分のバージョンを書くことにしました。

次のようなステートメントを使用して、要素ごとの行列の乗算を行うコードを実現しようとしています。

matrix m1, m2, m3;
m3 = m1 * m2;

ここでは、乗算の出力を効率的に返すことに関して、C++11 のムーブ セマンティクスを利用したいと思います。

これは私がこれまでに持っているものです。

#include "boost\numeric\ublas\matrix.hpp"
#include <Windows.h>
typedef boost::numeric::ublas::matrix<float> matrix;
void ElemProd();
const size_t X_SIZE = 400;
const size_t Y_SIZE = 400;
const size_t ITERATIONS = 500;
matrix operator*(const matrix &m1, const matrix &m2)
{
    size_t rows = m1.size1();
    size_t cols = m2.size2();
    matrix temp(rows,cols);
    for (size_t i = 0; i < rows; i++)
    {
        for (size_t j = 0; j < cols; j++)
        {
            temp(i, j) = m1(i, j) * m2(i, j);
        }
    }

    //return std::move(temp);
    return temp;
 }

void ElemProd()
{
     matrix m1(X_SIZE, Y_SIZE);
     matrix m2(X_SIZE, Y_SIZE);
     for (size_t i = 0; i < X_SIZE; i++)
     {
         for (size_t j = 0; j < Y_SIZE; j++)
         {
             m1(i, j) = 2;
             m2(i, j) = 10;
         }
     }

         matrix m3 = m1; // simply to allocate the right amount of memory for m3, to be overwritten.
         m3 = m1 * m2;
   }

ここでは、operator* オーバーロードで、計算結果を格納する一時行列を作成する必要がありました。これはかなりのオーバーヘッドを追加していると思います。これを回避する方法はありますか?

別のオプションは、オーバーロードへの引数を const ではなく、行列の 1 つを上書きして返すことですが、これは長期的には非常にリスクが高いと思います。避けたいと思います。

次のようなものが必要な場合を考えてみましょう:

行列 m = m1 * m2 * m3 * m4 * m5 * m6;

ここでは、実装で temp に 6 回メモリを割り当てていることがわかります。m は 1 回だけ割り当てる必要があります。それ以上の割り当ては単なるオーバーヘッドです。

4

0 に答える 0