Матричное матричное умножение Eigen3 в 30 раз быстрее, чем собственный распараллеленный код openmp. - PullRequest
0 голосов
/ 18 января 2019

Я скомпилировал приведенный ниже код на 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;
}
...