Я скомпилировал приведенный ниже код на VS C ++ 2017 с помощью / openmp / O2 / arch :: AVX.
При работе с 8 потоками вывод:
dt_loops = 1562мс
dt_eigen = 26 мс
Я ожидал, что A * B будет быстрее, чем мои собственные петли ручной работы, но я не ожидал такой большой разницы. Что-то не так с моим кодом? А если нет, то как Eigen3 может сделать это намного быстрее?
Я не очень опытен в использовании OpenMP или любого другого метода распараллеливания. Я пробовал разные порядки зацикливания, но приведенный ниже самый быстрый.
#include <iostream>
#include <chrono>
#include <Eigen/Dense>
int main() {
std::chrono::time_point<std::chrono::system_clock> start1, end1, start2, end2;
int n = 1000;
Eigen::MatrixXd A = Eigen::MatrixXd::Random(n, n);
Eigen::MatrixXd B = Eigen::MatrixXd::Random(n, n);
Eigen::MatrixXd C = Eigen::MatrixXd::Zero(n, n);
start1 = std::chrono::system_clock::now();
int i, j, k;
#pragma omp parallel for private(i, j, k)
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
for (k = 0; k < n; ++k) {
C(i, j) += A(i, k) * B(k, j);
}
}
}
end1 = std::chrono::system_clock::now();
std::cout << "dt_loops = " << std::chrono::duration_cast<std::chrono::milliseconds>(end1-start1).count() << " ms" << std::endl;
Eigen::MatrixXd D = Eigen::MatrixXd::Zero(n, n);
start2 = std::chrono::system_clock::now();
D = A * B;
end2 = std::chrono::system_clock::now();
std::cout << "dt_eigen = " << std::chrono::duration_cast<std::chrono::milliseconds>(end2-start2).count() << " ms" << std::endl;
}