矩阵乘法性能,int vs double

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了矩阵乘法性能,int vs double相关的知识,希望对你有一定的参考价值。

我正在尝试使用MPI进行矩阵乘法,并想请求一些帮助来解决一个问题。该机器有6个内核,32KB L1缓存,256KB L2缓存和15MB三级缓存。乘法如下:

vector<vector<double>> mult_mpi(vector<vector<double>> m, 
                                vector<vector<double>> n) { 
    int rows = m.size();
    int size = n.size();
    vector<vector<double>> r(rows, vector<double>(size));

    for (int i = 0; i < rows; ++i) 
        for (int k = 0; k < size; ++k) 
            for (int j = 0; j < size; ++j) 
                r[i][j] += m[i][k] * n[k][j];
    return r;
}

我对int也一样:

vector<vector<int>> mult_mpi(vector<vector<int>> m, vector<vector<int>> n);

然后我做了一些情节,不同的线条颜色表示节点的数量。

下图显示了将两个int矩阵相乘所花费的时间:

enter image description here

下图显示了将两个双矩阵相乘所花费的时间:

enter image description here

为什么我在双壳中获得4和6个节点的相同时间?我是否在内存带宽上遇到了限制?

我在最后一小时尝试了多次,结果相同。还检查机器负载与top,但在我的眼睛,我一个人在那里。

答案

你确定你没有计时4K矢量<>的分配...?

vector<vector< >>不适合挤压最佳性能。矩阵乘法是关于存储器访问的可伸缩性和“计算密度”的最佳操作之一。实际上,操作数量为O(N ^ 3),而数据数量为O(N ^ 2)。

实际上它用于对地球上的top500 fastest systems进行基准测试:HPL用于“高性能linpack”,是linpack一个线性algebral的参考实现。猜猜是什么...基准测试中使用的操作是DGEMM,即“双精度GEneral矩阵矩阵乘法”。

DGEMM是BLAS库中操作的名称,是线性代数的事实标准。今天有许多本地优化的BLAS库,无论是商业(INTEL MKL,IBM ESSL,...)还是开源(ATLAS),但它们都使用相同的原始(最初是fortran,现在也是C)BLAS接口。 (注意:the original implementation未优化)

基于BLAS还有LAPACK库:系统解算器,eigensystems,...还有优化的lapack库,但通常使用优化的BLAS库来挤压90%的性能。

我非常清楚一个(不是唯一一个...... HPL是另一个)强大的基于MPI的并行库,它是SCALAPACK,它包含PBLAS(并行BLAS),并且在其中... DGEMM的优化和并行版本等等。

SCALAPACK附带SLUG,您可以在其中找到块循环分布的优秀解释,这是用于在并行系统上挤压最佳性能排列线性代数问题的数据分布策略。

但是,要获得最佳性能,您需要将MPI可执行文件与本地优化的BLAS库链接。或者自己写,但你并不孤单,所以不要重新发明轮子。

获取局部优化不是按行,也不是按列访问矩阵,而是按块访问矩阵。调整块大小以优化缓存和/或TLB的使用(我记得刚才libgoto,另一个blas库,为了最小化TLB未命中而优化,在某些系统上达到并超过了英特尔MKL。 .. 过去)。例如,在这个ATLAS paper中查找更多信息。

在任何情况下,如果你真的想...我会开始分析其他车轮是如何锻造的,然后再尝试制造我的;)

以上是关于矩阵乘法性能,int vs double的主要内容,如果未能解决你的问题,请参考以下文章

性能数组乘法 Pearson

文心一言 VS 讯飞星火 VS chatgpt (23)-- 算法导论4.2 5题

矩阵乘法性能 numpy 和 eigen c++

如何进一步优化矩阵乘法的性能?

matlab中怎样将double型矩阵转换为int8型矩阵

使用 valgrind 进行平铺矩阵乘法的 C++ 性能分析