比numpy/scipy openblas慢性 mkl或开放式布拉斯

Eigen + MKL or OpenBLAS slower than Numpy/Scipy + OpenBLAS

本文关键字:mkl 开放式 布拉斯 慢性 openblas numpy scipy      更新时间:2023-10-16

我从C atm开始,想要使用矩阵并加快速度。之前与Python Numpy OpenBlas合作。认为C 特征 MKL可能更快或至少较慢。

我的C 代码:

#define EIGEN_USE_MKL_ALL
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/LU>
#include <chrono>
using namespace std;
using namespace Eigen;
int main()
{
    int n = Eigen::nbThreads( );
    cout << "#Threads: " << n << endl;
    uint16_t size = 4000;
    MatrixXd a = MatrixXd::Random(size,size);
    clock_t start = clock ();
    PartialPivLU<MatrixXd> lu = PartialPivLU<MatrixXd>(a);
    float timeElapsed = double( clock() - start ) / CLOCKS_PER_SEC; 
    cout << "Elasped time is " << timeElapsed << " seconds." << endl ;
}

我的python代码:

import numpy as np
from time import time
from scipy import linalg as la
size = 4000
A = np.random.random((size, size))
t = time()
LU, piv = la.lu_factor(A)
print(time()-t)

我的时间:

C++     2.4s
Python  1.2s

为什么C 比Python慢?

我正在使用:

编译C
g++ main.cpp -o main -lopenblas -O3 -fopenmp  -DMKL_LP64 -I/usr/local/include/mkl/include

MKL肯定有效:如果我禁用它,则运行时间约为13s。

我还尝试了C OpenBlas,这也给了我2.4左右。

为什么C 和EIGEN比Numpy/Scipy慢?

时间是错误的。这是壁时钟时间与CPU时间的典型症状。当我从<chrono>标头中使用system_clock时,它"神奇地"变得更快。

#define EIGEN_USE_MKL_ALL
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/LU>
#include <chrono>
int main()
{
    int const n = Eigen::nbThreads( );
    std::cout << "#Threads: " << n << std::endl;
    int const size = 4000;
    Eigen::MatrixXd a = Eigen::MatrixXd::Random(size,size);
    auto start = std::chrono::system_clock::now();
    Eigen::PartialPivLU<Eigen::MatrixXd> lu(a);
    auto stop = std::chrono::system_clock::now();
    std::cout << "Elasped time is "
              << std::chrono::duration<double>{stop - start}.count()
              << " seconds." << std::endl;
}

i用

编译
icc -O3 -mkl -std=c++11 -DNDEBUG -I/usr/include/eigen3/ test.cpp

并获取输出

#Threads: 1
Elasped time is 0.295782 seconds.

您的Python版本在我的机器上报告0.399146080017


另外,要获得可比较的时机,您可以在Python中使用time.clock()(CPU时间),而不是time.time()(壁时钟时间)。

这不是一个公平的比较。Python例程以浮点精度运行,而C 代码需要重复加倍。这恰好使计算时间加倍。

>>> type(np.random.random_sample())
<type 'float'>

您应该与MatrixXf而不是MatrixXd进行比较,并且您的MKL代码应同样快。