(2019年9月14日)
■使用ソフト
・Visual Studio Community 2019
■言語
・C/C++
■Windows SDK バージョン
・10.0.17763.0
※Windows SDK バージョンの変更方法
■使用ライブラリ
・Eigen 3.3.7
※Eigen行列計算ライブラリ導入方法
■手順
1.以下をベースにコード変更する。
【C++】 メッセージボックスの作成
2.C++ファイル(.cpp)を以下のとおり変更する。
#include <windows.h>
#include <Eigen/Core>
#include <chrono>
#include <vector>
//------------------------------------------------------------
// MultMtx()関数:行列の積
//------------------------------------------------------------
void MultMtx(std::vector<std::vector<double> >& mtx1, std::vector<std::vector<double> >& mtx2, std::vector<std::vector<double> >& resultMtx)
{
for (int i = 0; i < (int)mtx1.size(); i++)
{
for (int j = 0; j < (int)mtx2[0].size(); j++)
{
double sum = 0;
for (int k = 0; k < (int)mtx2.size(); k++)
{
sum += mtx1[i][k] * mtx2[k][j];
}
resultMtx[i][j] = sum;
}
}
}
//--------------------------------------------------------------------------------------
// wWinMain()関数:エントリーポイント
//--------------------------------------------------------------------------------------
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
WCHAR wcText[256];
//------------------------------------------------------------
// Eigenを使用した行列の積
//------------------------------------------------------------
auto Start = std::chrono::system_clock::now();//時間計測開始
Eigen::MatrixXd mat1 = Eigen::MatrixXd::Constant(100, 100, 0.011);
Eigen::MatrixXd mat2 = Eigen::MatrixXd::Constant(100, 100, 0.011);
for (int i = 0; i < 100; i++)
{
mat1 *= mat2;
}
auto End = std::chrono::system_clock::now();//時間計測終了
auto Calc = End - Start;
auto Time = std::chrono::duration_cast<std::chrono::milliseconds>(Calc).count();
//------------------------------------------------------------
// std::vectorを使用した行列の積
//------------------------------------------------------------
auto Start2 = std::chrono::system_clock::now();//時間計測開始
std::vector<std::vector<double> > mat3(100, std::vector<double>(100, 0.011));
std::vector<std::vector<double> > mat4(100, std::vector<double>(100, 0.011));
std::vector<std::vector<double> > result(100, std::vector<double>(100));
for (int i = 0; i < 100; i++)
{
MultMtx(mat3, mat4, result);
mat3 = result;
}
auto End2 = std::chrono::system_clock::now();//時間計測終了
auto Calc2 = End2 - Start2;
auto Time2 = std::chrono::duration_cast<std::chrono::milliseconds>(Calc2).count();
//------------------------------------------------------------
// 出力
//------------------------------------------------------------
swprintf(wcText, 256, L"%lf, %lld, %lf, %lld", mat1(0, 0), Time, mat3[0][0], Time2);
MessageBox(NULL, wcText, L"Eigen", MB_OK);
return 0;
}
#include <Eigen/Core>
#include <chrono>
#include <vector>
//------------------------------------------------------------
// MultMtx()関数:行列の積
//------------------------------------------------------------
void MultMtx(std::vector<std::vector<double> >& mtx1, std::vector<std::vector<double> >& mtx2, std::vector<std::vector<double> >& resultMtx)
{
for (int i = 0; i < (int)mtx1.size(); i++)
{
for (int j = 0; j < (int)mtx2[0].size(); j++)
{
double sum = 0;
for (int k = 0; k < (int)mtx2.size(); k++)
{
sum += mtx1[i][k] * mtx2[k][j];
}
resultMtx[i][j] = sum;
}
}
}
//--------------------------------------------------------------------------------------
// wWinMain()関数:エントリーポイント
//--------------------------------------------------------------------------------------
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
WCHAR wcText[256];
//------------------------------------------------------------
// Eigenを使用した行列の積
//------------------------------------------------------------
auto Start = std::chrono::system_clock::now();//時間計測開始
Eigen::MatrixXd mat1 = Eigen::MatrixXd::Constant(100, 100, 0.011);
Eigen::MatrixXd mat2 = Eigen::MatrixXd::Constant(100, 100, 0.011);
for (int i = 0; i < 100; i++)
{
mat1 *= mat2;
}
auto End = std::chrono::system_clock::now();//時間計測終了
auto Calc = End - Start;
auto Time = std::chrono::duration_cast<std::chrono::milliseconds>(Calc).count();
//------------------------------------------------------------
// std::vectorを使用した行列の積
//------------------------------------------------------------
auto Start2 = std::chrono::system_clock::now();//時間計測開始
std::vector<std::vector<double> > mat3(100, std::vector<double>(100, 0.011));
std::vector<std::vector<double> > mat4(100, std::vector<double>(100, 0.011));
std::vector<std::vector<double> > result(100, std::vector<double>(100));
for (int i = 0; i < 100; i++)
{
MultMtx(mat3, mat4, result);
mat3 = result;
}
auto End2 = std::chrono::system_clock::now();//時間計測終了
auto Calc2 = End2 - Start2;
auto Time2 = std::chrono::duration_cast<std::chrono::milliseconds>(Calc2).count();
//------------------------------------------------------------
// 出力
//------------------------------------------------------------
swprintf(wcText, 256, L"%lf, %lld, %lf, %lld", mat1(0, 0), Time, mat3[0][0], Time2);
MessageBox(NULL, wcText, L"Eigen", MB_OK);
return 0;
}
3.実行結果(Eigenを使用した行列の積とstd::vectorを使用した行列の積の速度比較)
・Eigenを使用した行列の積→5.729秒
・std::vectorを使用した行列の積→8.552秒
【Releaseモードの場合】
・Eigenを使用した行列の積→0.025秒
・std::vectorを使用した行列の積→0.09秒
4.参考文献
ベクトル/行列演算の定番ライブラリEigen
【C++】Eigen関数一覧
C言語による標準アルゴリズム辞典
0 件のコメント:
コメントを投稿