Я хочу использовать библиотеку Eigen
для выполнения вычислений линейной алгебры. В частности, я хочу умножить случайный вектор на случайную матрицу. Вот код, я использую:Умножение векторной матрицы с 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 микросекунды против 5300 микросекунд с моим кодом C++
.
Любая идея о том, почему это так медленно и как это сделать быстрее?
EDIT
Я не отправляя код, который я написал, потому что это часть гораздо большего программного обеспечения и делая MWE из него потребует много работы. Вместо этого я собираюсь описать, что он делает: я определил классы для векторов и матриц, которые обертывают std::vector
s, затем для выполнения умножения я определяю определенное число thread
s, разбивая матрицу на куски и каждый из thread
вычисляет линейную комбинацию строк по коэффициентам в векторе. Каждый thread
записывает свой частичный результат в другой вектор строки, и, наконец, все векторы суммируются для получения конечного результата. Очень просто. Кстати, я использую 4 thread
s, хотя это значение может быть оптимизировано.
Добавьте команду '-O2' или' -O3' в команду компиляции. –
@AviGinsburg Спасибо! Я очень смущен, что забыл об этом ... Во всяком случае с '-O2',' -O3' или даже '-Ofast' время не опускается ниже 21500 микросекунд, что по-прежнему в 4 раза медленнее моего кода! – minomic
Не забудьте отправить код, с которым вы его сравниваете? –