我想使用该库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
的代码s,它的运行速度比我上面粘贴的代码快大约 54 倍!特别是,在我的机器上,它是 286904 微秒,而我的 C++
为 5300 微秒。代码。
为什么这么慢以及如何让它更快?
我不会发布我编写的代码,因为它是一个更大的软件的一部分,用它制作 MWE 需要大量工作。相反,我将描述它的作用:我为包装 std::vector
的向量和矩阵定义了类。 s,然后为了进行乘法,我定义了一定数量的 thread
s,将矩阵分成 block ,每个 block thread
根据向量中的系数计算行的线性组合。每个thread
将其部分结果写入另一个行向量,最后将所有向量相加得到最终结果。很简单。顺便说一句,我正在使用 4 thread
s,尽管这个值可能会被优化。
最佳答案
除了添加 -O2
或-O3
对于您的编译标志(如评论中指出的),您应该更改 s
的类型和b
至Matrix<unsigned int,1,Dynamic>
。如果 Eigen 在编译时知道乘积的因素之一是向量,则它可以使用更快的乘积实现。
在我的机器上,执行时间从 25392 µs 更改为 4751 µs。
但是,目前您不会从矩阵向量乘积的多线程中受益(Eigen 3.3rc1)。
关于matrix - 向量矩阵乘法与特征值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39723461/