首页 > 其他分享 >矩阵乘法的指令集加速例子

矩阵乘法的指令集加速例子

时间:2023-04-27 09:55:05浏览次数:34  
标签:const Mat int 矩阵 cols 指令集 800 ptr 乘法

这里就不介绍基本概念了,直接给代码和对比结果。分别是普通C++代码,SSE加速代码和OpenCV代码。代码基于VS2017、OpenCV430和Qt5.9。CPU型号是Intel Core i5-7400。

Mat mul1(const Mat& a, const Mat& b)
{
    ASSERT(a.cols == b.rows);
#define COUNT a.cols
    Mat c = Mat::zeros(a.rows, b.cols, CV_32FC1);
    for (int i = 0; i < c.rows; i++)
    {
        const float *aptr = a.ptr<float>(i);
        float *optr = c.ptr<float>(i);
        for (int k = 0; k < COUNT; k++)
        {
            const float* bptr = b.ptr<float>(k);
            for (int j = 0; j < c.cols; j++)
            {
                optr[j] += aptr[k] * bptr[j];
            }
        }
    }
#undef COUNT
    return c;
}

Mat mul2(const Mat& a, const Mat& b)
{
    ASSERT(a.cols == b.rows);
#define COUNT a.cols
    Mat c = Mat::zeros(a.rows, b.cols, CV_32FC1);
    int max4 = c.cols / 4 * 4;
    for (int i = 0; i < c.rows; i++)
    {
        const float *aptr = a.ptr<float>(i);
        float *optr = c.ptr<float>(i);
        for (int k = 0; k < COUNT; k++)
        {
            const float* bptr = b.ptr<float>(k);
            for (int j = 0; j < max4; j += 4)
            {
                __m128 mma = _mm_set_ps1(aptr[k]);
                __m128 mmb = _mm_loadu_ps(&bptr[j]);
                __m128 mmo = _mm_loadu_ps(&optr[j]);
                __m128 sum = _mm_fmadd_ps(mma, mmb, mmo); /* FMA */
                _mm_storeu_ps(&optr[j], sum);
            }
            for (int j = max4; j < c.cols; j++)
            {
                optr[j] += aptr[k] * bptr[j];
            }
        }
    }
#undef COUNT
    return c;
}

void main()
{
    Mat image = Mat::zeros(1600, 1600, CV_8UC1);
    circle(image, Point2i(800, 800), 200, 255, -1);
    Mat a, b;
    image.convertTo(a, CV_32FC1, 0.0039);
    image.convertTo(b, CV_32FC1, 0.0039);
    int64 t1, t2;

    Mat result1;
    t1 = getTickCount();
    result1 = mul1(a, b);
    t2 = getTickCount();
    qDebug() << u8"diy(ms):" << (t2 - t1) / getTickFrequency() * 1000;

    Mat result2;
    t1 = getTickCount();
    result2 = mul2(a, b);
    t2 = getTickCount();
    qDebug() << u8"mul2(ms)" << (t2 - t1) / getTickFrequency() * 1000;

    Mat result3;
    t1 = getTickCount();
    result3 = a * b;
    t2 = getTickCount();
    qDebug() << u8"cv(ms)" << (t2 - t1) / getTickFrequency() * 1000;

    qDebug() << result1.at<float>(800, 800) << result2.at<float>(800, 800) << result3.at<float>(800, 800);
}

下面是Release版程序的文本输出。可见计算结果跟OpenCV尾数稍有区别,可能是浮点数精度问题。SSE的效率要超过OpenCV的速度:

diy(ms): 3028.05
mul2(ms) 1165.66
cv(ms) 2454.72
396.603 396.603 396.601

 

标签:const,Mat,int,矩阵,cols,指令集,800,ptr,乘法
From: https://www.cnblogs.com/mengxiangdu/p/17358084.html

相关文章

  • 1351. 统计有序矩阵中的负数(leetcode)
    https://leetcode.cn/problems/count-negative-numbers-in-a-sorted-matrix/1351.统计有序矩阵中的负数1.二分法:把每一行进行一遍二分,找到正数与负数的边界,且此时grid[i][mid]也为负数,即边界下标的对应值是负数的左半边界那么一行中的个数即为size()-lclassSolution{pu......
  • 测试矩阵相乘
      #include<QtWidgets/QApplication>#include<QtWidgets/QGraphicsScene>#include<QtWidgets/QGraphicsView>#include<QtCore/QPointF>#include<QtCore/QDebug>//定义矩阵类classMatrix{public:Matrix(fl......
  • 矩阵旋转,仿射变换
    importnumpyasnpimportmathasmdefRx(theta):returnnp.matrix([[1,0,0],[0,m.cos(theta),-m.sin(theta)],[0,m.sin(theta),m.cos(theta)]])defRy(theta):returnnp.matrix([[......
  • 大规模 Transformer 模型 8 比特矩阵乘简介 - 基于 Hugging Face Transformers、Accel
    引言语言模型一直在变大。截至撰写本文时,PaLM有5400亿参数,OPT、GPT-3和BLOOM有大约1760亿参数,而且我们仍在继续朝着更大的模型发展。下图总结了最近的一些语言模型的尺寸。由于这些模型很大,因此它们很难在一般的设备上运行。举个例子,仅推理BLOOM-176B模型,你就需要8......
  • 【DP】LeetCode 1277. 统计全为 1 的正方形子矩阵
    题目链接1277.统计全为1的正方形子矩阵思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律在数组的动态规划问题中,一般dp[i]都是表示以nums以前i个元素组成(即nums[i-1])的状态;dp[i][j]分别表示以nums1......
  • hdu 5446 长春区域赛网络赛1010 Unknown Treasure(lucas定理+中国剩余定理+移位乘法)
    题目链接:hdu5446题目大意:求出Cmn%M,M=p1⋅p2⋯pk题目分析:首先对于每个质数pi我们,我们可以利用Lucas定理求出Cmn%pi的值,Lucas定理如下:Cmn%p=Cm/pn/p⋅Cm%pn%p%p然后我们可以利用中国剩余定理求取最后答案:M=∏i=1kpi,Mi=M/piCmn%M=∑i=1kCmn%pi⋅Mi⋅inv[Mi]因为做乘法......
  • MKL稀疏矩阵运算示例及函数封装
    IntelMKL库提供了大量优化程度高、效率快的稀疏矩阵算法,使用MKL库的将大型矩阵进行稀疏表示后,利用稀疏矩阵运算可大量节省计算时间和空间,但由于MKL中的原生API接口繁杂,因此将常用函数封装,便于后续使用,最后在实际例子中调用接口执行想要的矩阵运算。0稀疏矩阵稀疏矩阵是指矩阵......
  • MKL普通矩阵运算示例及函数封装
    本示例将介绍MKL中的矩阵乘法和求逆,使用MKL进行此类大型矩阵运算可大量节省计算时间和空间,但由于MKL中的原生API接口繁杂,因此将常用函数封装,便于后续使用,最后在实际例子中调用接口执行想要的矩阵运算。1MKL矩阵乘法案例所用示例如下,矩阵A、B分别为\[A={\left[{\begin{array......
  • 51单片机学习笔记 STC89C52RC (05)矩阵键盘和独立键盘(轻触开关)
    按键抖动,需要消抖 原理图来自清翔电子一、独立键盘模块1.可以直接获取 P3^0对应S2 P3^1对应S3 P3^2对应S4 P3^3对应S5 的电压当轻触开关按下时,电流会流向GND,此时这一路的电压为0V,松开轻触开关,又变为5V //第一种方法:单个I/O口检测控制#include<reg51.h>sbi......
  • 文章学习:基于AVX-512指令集的同态加密算法中大整数运算性能优化与突破
    学习文章:英特尔×同态科技|基于AVX-512指令集的同态加密算法中大整数运算性能优化与突破文章人工智能的安全隐患ChatGPT的成功大部分来源于海量的数据支撑和丰富的数据维度,基于13亿参数量的庞大模型,随着用户的不断涌入,ChatGPT不断迭代进化新的“知识”,而在模型表达能力的增......