4

我正在尝试使用英特尔 MKL 库使用它们提供的 Boost::uBLAS 接口(包括 mkl_boost_ublas_matrix_prod.hpp)执行矩阵乘法。我的数据只是整数,所以我尝试将我的矩阵模板类型更改为 int 并且性能下降了,这主要是由于代码只使用了一个 CPU 内核而不是我可用的 12 个内核。我在 MKL 文档中找不到任何东西来解释为什么整数没有使用 MKL 的 OpenMP 多线程功能(我猜他们根本没有使用 MKL?)。

此外,与浮点数相比,我看到双打的性能下降了 50%。

问题:

  1. 为什么浮点数和双精度数之间存在差异?
  2. 为什么我不能使用整数?

以下是我从以下代码得出的结果:

  matrix<float>(10000x10000):  13 seconds (12 threads used)
 matrix<double>(10000x10000):  26 seconds (12 threads used)
    matrix<int>(10000x10000):  >1000 seconds (1 thread used, stopped early)
  matrix<float>(25000x25000): 187 seconds (12 threads used)
 matrix<double>(25000x25000): 401 seconds (12 threads used)

使用的代码(根据需要替换两个 matrix< type > 行):

#include <boost/numeric/ublas/matrix.hpp>
#include <mkl_boost_ublas_matrix_prod.hpp>

using namespace boost::numeric::ublas;

void benchmark() {

    int size = 10000;
    matrix<float> m(size, size);
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j) {
            m(i,j) = 2*i-j;
        }
    }
    matrix<float> r(size, size);
    r = prod(m,m);
}

int main(int argc, char *argv[]) {
    benchmark();
    return 0;
}

编译:

 g++ Flags: -std=c++0x -O3 -DNDEBUG -DMKL_ILP64  -m64 -msse4.2 -march=native -mtune=native
 ld Flags:  -lmkl_intel_ilp64 -lmkl_gnu_thread -lmkl_core -fopenmp -lpthread -lm

处理器:

 Intel Xeon E7530 with 6 Cores (x2) with HT. 

MKL 不使用超线程,因为他们说这对任何事情都没有帮助,所以我有 12 个线程可用,而不是 24 个。

4

1 回答 1

7

为什么浮点数和双精度数之间存在差异?

现代 CPU 使用向量指令来执行浮点运算。这些指令具有固定的吞吐量和长度,例如英特尔至强 E7530 的每个内核能够在每个周期处理两个 128 位加法或乘法。这导致每个周期有 4 个双精度数或 8 个浮点数。

为什么我不能使用整数?

ublas 示例中的模板将浮点和双精度模板的矩阵乘法映射到 MKL SGEMM 和 DGEMM 函数。当您将矩阵模板从 float/double 更改为 int 时,BOOST 使用矩阵乘法的参考实现,因为 MKL 不支持整数矩阵乘法。

于 2012-08-01T10:11:30.343 回答