首页 > 其他分享 >向量化实现矩阵运算优化(一)

向量化实现矩阵运算优化(一)

时间:2023-09-28 16:26:43浏览次数:36  
标签:运算 int res 矩阵 xsimd vector 量化 loop size

xsimd简介

  xsimd是C++的一个开源simd库,实现了对常见simd指令的封装,从而使得simd的操作更为简单。接下来先从两个简单的例子来入门xsimd。

void average(const std::vector<double>& v1, const std::vector<double>& v2, std::vector<double>& v) {
    int n = v.size();
    int size = xsimd::batch<double, xsimd::avx>::size;
    int loop = n - n % size;

    for (int i = 0; i < loop; i += size) {
        auto a = xsimd::batch<double>::load_unaligned(&v1[i]);
        auto b = xsimd::batch<double>::load_unaligned(&v2[i]);
        auto res = a + b; 
        res.store_unaligned(&v[i]);
    }
    for (int i = loop; i < n; ++i) 
        v[i] = v1[i] + v2[i];
}

  上述demo实现了两个向量相加的操作,由于每次都能从vector当中加载size个数据,因此对剩余的不能进行vectorize的数据进行了分别处理。比如说,有一百个数据,每次处理8个数据,到最后剩下4个数不能凑到8,所以用朴素的迭代方式进行求和。这个demo是非对齐内存的处理方式。

using vector_type = std::vector<double, xsimd::default_allocator<double>>;
std::vector<double> v1(1000000), v2(1000000), v(1000000);
vector_type s1(1000000), s2(1000000), s(1000000);

void average_aligned(const vector_type& s1, const vector_type& s2, vector_type& s) {
    int n = s.size();
    int size = xsimd::batch<double>::size;
    int loop = n - n % size;

    for (int i = 0; i < loop; i += size) {
        auto a = xsimd::batch<double>::load_aligned(&s1[i]);
        auto b = xsimd::batch<double>::load_aligned(&s2[i]);
        auto res = a + b;
        res.store_aligned(&s[i]);
    }

    for (int i = loop; i < n; ++i) 
        s[i] = s1[i] + s2[i];
}

  要实现对齐内存的操作方式,我们必须对vector指定特定的分配器,不然最后运行出来的代码会出现segment fault。

  总之,要记住常用的api,load_aligned, store_aligned, load_unaligned, store_unaligned,它们分别对应了内存对齐与否的处理方式。接下来我们再讲解另外一个demo,并且提供与openmp的性能对比。

auto sum(const std::vector<double>&v) {
    int n = v.size();
    int size = xsimd::batch<int>::size;
    int loop = n - n % size;

    double res{};
    for (int i = 0; i < loop; ++i) {
        auto tmp = xsimd::batch<int>::load_unaligned(&v[i]);
        res += xsimd::hadd(tmp);
    }

    for (int i = loop; i < n; ++i) {
        res += v[i];
    }

    return res;
}

auto aligned_sum(const std::vector<double, xsimd::default_allocator<double>>& v) {
    int n = v.size();
    int size = xsimd::batch<int>::size;
    int loop = n - n % size;

    double res{};
    for (int i = 0; i < loop; ++i) {
        auto tmp = xsimd::batch<int>::load_aligned(&v[i]);
        res += xsimd::hadd(tmp);
    }

    for (int i = loop; i < n; ++i) {
        res += v[i];
    }
    
    return res;
}

  这个例子实现了对向量求和的功能。总体与前面基本一样,这里hadd是一个对向量求和的函数。

  对于openmp的向量化实现,则较为简单,只需要在for循环上面加上特定指令即可。不过需要注意的是,openmp支持C语法,有一些C++的新特性可能并不支持,而且需要把花括号放到下一行,我们来看具体操作。

auto parallel_sum(const std::vector<double>& v) {
    double res{};

    int n = v.size();
    #pragma omp simd
    for (int i = 0; i < n; ++i)
        res += v[i];

    return res;
}

  不要忘记加上编译选项-fopenmp和-march=native,为了性能测试,我开启了O2优化,以下是简单的测试结果,数据规模是一千万。

  一般情况下进行了内存对齐都会比没有对齐的要快一些,同时可以看到openmp与xsimd也差了一个量级。当然不同平台的结果可能会有差异,需要用更专业的工具进行测量比较。

标签:运算,int,res,矩阵,xsimd,vector,量化,loop,size
From: https://www.cnblogs.com/ChebyshevTST/p/17736015.html

相关文章

  • 四则运算
    软件工程计科21级四班作业地址https://edu.cnblogs.com/campus/gdgy/CSGrade21-12/homework/13016作业目标结对项目GitHub地址https://github.com/2077435277/FourOperation成员信息姓名学号冯威炀3121005123曾中港3121005151PSP表格P......
  • 用 Python 自动生成小学四则运算题目
    这个作业属于哪个课程软件工程这个作业要求在哪里结对项目这个作业的目标熟悉多人协作成员......
  • 结对项目:实现自动生成小学四则运算题目
    软件工程计科21级2班作业要求结对项目-实现四则运算题目生成作业目标合作完成四则运算题目生成项目成员信息姓名学号杨恒3121005146游烽3121005148Github:https://github.com/wcng010/SoftwareWork2PSP表格PSP2.1PersonalSoftwarePr......
  • Matlab : 数值运算
    学习一门技术最好的方式就是阅读官方文档,可以查看MATLAB官方文档多项式的数值运算使用MATLAB表示多项式使用向量表示多项式在MATLAB中,多项式可以用向量表示,向量中的元素为多项式的系数(降幂排序):第一位为多项式最高次项系数,最后一位为常数项.例如多项式:f(x)=x3−2x......
  • 结对项目:自动生成小学四则运算题目
    所属课程软件工程导论作业要求个人项目作业目标熟悉结对编程、完成小学四则运算题目的自动生成小组成员姓名班级学号林劲辰计科2班3121004707许庆阳计科2班3121004931Github链接:https://github.com/HsuQingYoung/PeerWork项目要求1、......
  • 结对项目:用python实现一个自动生成小学四则运算题目的命令行程序
    这个作业属于哪个课程计科21级12班这个作业的要求在哪里结对项目这个作业的目标了解结对项目的过程团队成员信息姓名学号肖兴明3121004712徐强3121004713Github链接GithubPSPPSP2.1PersonalSoftwareProcessStages预估耗时(分钟)实......
  • 结对项目:自动生成小学四则运算题目
    软件工程https://edu.cnblogs.com/campus/gdgy/CSGrade21-12?filter=all作业要求https://edu.cnblogs.com/campus/gdgy/CSGrade21-12/homework/13016作业目标学习算法,完成简单的四则运算团队成员:姓名:陈鑫杰学号:3121004688姓名:黄嘉俊学号:3121004696Git链接:h......
  • 三维模型3DTile格式轻量化压缩处理重难点分析
    三维模型3DTile格式轻量化压缩处理重难点分析 在对三维模型3DTile格式进行轻量化压缩处理的过程中,存在一些重要而又困难的问题需要解决。以下是几个主要的重难点:1、压缩率和模型质量之间的平衡:压缩技术的目标是尽可能地减少数据大小,但过度的压缩会降低模型的精度,影响最终的视......
  • 矩阵乘法
    别人的博客Luogu-P3390【模板】矩阵快速幂#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;#definedebug(x)cout<<#x<<"="<<x<<endl;constintN=105,M=1e9+7;intn;llk;inlinellread(){ lls=0,......
  • 小学四则运算题目生成器
    这个作业属于哪个课程软件工程这个作业要求在哪里在这里这个作业的目标写个小学四则运算题目生成器,学会与同伴合作做项目陈威衡3121005206郑贵南3121005237github连接需求分析表达式中的分数都用真分数的形式表示生成的表达式里只包含四则运算和括号每......