涉及临时内存分配时避免blas?

时间:2016-07-03 01:47:07

标签: c++ performance linear-algebra blas intel-mkl

我有一个程序可以反复计算矩阵乘积x'Ay。更好的做法是通过调用MKL的blas来计算它,即cblas_dgemvcblas_ddot,这需要将内存分配给临时向量,或者最好简单地取{的总和{1}}?换句话说,MKL的理论上是否会增加任何价值?

我为笔记本电脑进行了基准测试。每个测试几乎没有差异,除了g ++ _ no_blas执行的次数是其他测试的两倍(为什么?)。 O2,O3和Ofast之间也没有区别。

  1. g ++ _ blas_static 57ms
  2. g ++ _ blas_dynamic 58ms
  3. g ++ _ no_blas 100ms
  4. icpc_blas_static 57ms
  5. icpc_blas_dynamic 58ms
  6. icpc_no_blas 58ms
  7. util.h

    x_i * a_ij * y_j

    的main.cpp

    #ifndef UTIL_H
    #define UTIL_H
    
    #include <random>
    #include <memory>
    #include <iostream>
    
    struct rng 
    {
            rng() : unif(0.0, 1.0)
            {
            }
    
            std::default_random_engine re; 
            std::uniform_real_distribution<double> unif;
    
            double rand_double()
            {
                    return unif(re);
            }
    
            std::unique_ptr<double[]> generate_square_matrix(const unsigned N)
            {
                    std::unique_ptr<double[]> p (new double[N * N]);
                    for (unsigned i = 0; i < N; ++i)
                    {
                            for (unsigned j = 0; j < N; ++j)
                            {
                                    p.get()[i*N + j] = rand_double();
                            }
                    }
                    return p;
            }
    
            std::unique_ptr<double[]> generate_vector(const unsigned N)
            {
                    std::unique_ptr<double[]> p (new double[N]);
                    for (unsigned i = 0; i < N; ++i)
                    {
                            p.get()[i] = rand_double();
                    }
                    return p;
            }
    };
    
    #endif // UTIL_H
    

1 个答案:

答案 0 :(得分:0)

GCC没有blas很差,因为它不使用矢量化SMID指令,而其他人都这样做。 icpc会自动向量化你的循环。

您不会显示矩阵大小,但通常gemv是受内存限制的。由于矩阵比温度矢量大得多,因此消除它可能无法大幅提高性能。