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 回だけ割り当てる必要があります。それ以上の割り当ては単なるオーバーヘッドです。