【问题标题】:sgemm does not multithread when dgemm does - Intel MKL当 dgemm 执行时,sgemm 不执行多线程 - 英特尔 MKL
【发布时间】:2014-08-24 18:55:53
【问题描述】:

我正在使用英特尔 MKL 的 ?GEMM 函数来乘以矩阵。考虑以下两个矩阵乘法:

            cblas_?gemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m,n,k,
                            1.0,
                            Matrix1,k,
                            Matrix2,n,
                            0.0,
                            A,n);

其中 m=1E5,n=1E4,k=5。当我使用 pca_dgemm 和 pca_sgemm 时,它使用了所有 12 个内核,并且执行得很漂亮。

但是,当我执行以下矩阵乘法时:

    cblas_?gemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m,l,n,
                    1.0,
                    A,n,
                    Ran,l,
                    0.0,
                    Q,l);

其中 m=1E5、n=1E5 和 l=7(请注意,传递参数的顺序是不同的。这是 (m,n) * (n,l))。 pca_dgemm 使用了全部 12 个内核并且执行得很漂亮。

但是,pca_sgemm 没有。它只使用 1 个核心,当然,需要更长的时间。当然,对于 sgemm 我使用浮点数组,而对于 dgemm 我使用双精度数组。

为什么会这样?他们都给出了准确的结果,但 sgemm 只在前者上多线程,而 dgemm 多线程和两者!简单地更改数据类型怎么会产生这种差异?

请注意,所有数组都是使用 mkl_malloc 分配的,对齐方式为 64。

编辑 2:还请注意,当 l=12 时,换句话说,对于更大的矩阵,它会穿入 sgemm。换句话说,很明显 sgemm 版本需要更大的矩阵来并行化,而 dgemm 没有这个要求。这是为什么呢?

【问题讨论】:

    标签: c++ c multithreading blas intel-mkl


    【解决方案1】:

    MKL 函数预先做了很多工作来尝试猜测执行操作的最快方式是什么,因此在处理双精度或单精度时会做出不同的决定也就不足为奇了。

    在决定采用哪种策略时,必须权衡在单个线程中执行操作的成本与启动线程以并行执行操作的开销。将发挥作用的一个因素是 SSE 指令对单精度数的运算速度是双精度数的两倍,因此启发式方法很可能会决定对单精度数执行操作可能比在单精度数上执行 SSE SIMD 操作更快。单核而不是踢十二个线程来并行执行。具体可以并行执行多少取决于您的 CPU 架构的细节;例如,SSE2 可以对四个单操作数或两个双操作数进行操作,而最近的 SSE 指令集支持更广泛的数据。

    我过去发现,对于小型矩阵/向量,滚动您自己的函数通常比使用 MKL 更快。例如,如果您所有的操作都是在 3 向量和 3x3 矩阵上进行的,那么用纯 C 语言编写自己的 BLAS 函数会快得多,而使用 SSE 再次优化它们会更快(如果您能满足对齐约束)。对于 3 和 6 向量的混合,编写自己的优化 SSE 版本仍然更快。这是因为当操作较小时,MKL 版本决定使用哪种策略的成本会成为相当大的开销。

    【讨论】:

    • 感谢您提供的好信息,这似乎正是正在发生的事情。但是,它的决策策略似乎对我不利,因为单线程 sgemm 计算所用的时间几乎是多线程 dgemm 计算的十倍。您对如何推翻此决策有任何想法吗?
    • 不,AFAIK,知道不能。
    • 您可能对英特尔集成性能基元感兴趣:software.intel.com/en-us/articles/…
    猜你喜欢
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    相关资源
    最近更新 更多