OpenMP 版本稀疏矩阵向量乘

说明:

1.转载请联系本人

2.代码在最后

问题描述

稀疏矩阵向量乘法(Sparse Matrix-Vector Multiplication, SpMV)在许多科学计算程序中都有广泛的应用。
如下所示,数据矩阵A是稀疏的,输入向量x和输出向量y是稠密的。

y = Ax

要求

  1. 根据内存大小测不同规模和不同稀疏程度的稀疏矩阵的处理速度(GFLOPS/s)和带宽(GB/s),并给出计算公式。
  2. 请计算系统的理论峰值,如果没有达到理论峰值,尝试给出原因。

思路和方法

老师在/hw2目录下提供的代码已经能够达到比较好的存储访问了,所以在这个基础上添加OpenMP代码以及尝试其他的优化,如循环优化即可。

实验

结果及分析

不同规模和不同稀疏程度矩阵处理速度公式:
假设稀疏矩阵中不为0的个数为k
处理速度公式 = 2*k/1000000000/time
带宽计算公式 = (sizeof(int)*dim + sizeof(int)*k + sizeof(float)*k + sizeof(float)*dim*2)/1000000000/time

系统理论峰值(即浮点数理论峰值)
集群理论浮点峰值
= CPU主频(GHz)× CPU每时钟周期执行浮点运算次数 × 节点数 × 8(每节点双路四核)
=4.2*4*8=134.4GFLOPS/s

峰值带宽: B=F×D/8=2133MHz*64bit/8=17.064GHz
没有达到理论峰值的原因是,程序并不只是在做浮点数运算或只是在访问内存,以及操作系统的线程调度,和服务器本身的不稳定性等等...

1.尝试parallel shared/private以及dynamic

问题1: 发现在initMatrix里面加omp效果不佳.
解决: 可能会因为并行访问同一数值,导致访问错误和数组越界等问题有关

问题2: 发现使用shared/private之后速度较慢,GFLOPS较低
解决: 与privaet是否使用无关,主要是这样会导致并行区域开多,速度会下降

2.尝试parallel guided 和减少for循环依赖
代码如下

for(int i=1; i<=dim; i++)
     tmp[i-1] = row[i]; // 循环分离,减少依赖
for(int numOfTimes=0; numOfTimes<ITERATIONS; numOfTimes++){
  #pragma omp parallel for num_threads(thread_num)schedule(guided)
      for(unsigned short i=0; i<dim; i++){
        float t = 0;
        for(int j=row[i]; j<tmp[i]; j++){
          unsigned short colNum = col[j];
          t += data[j] * vec[colNum];
        }
        result[i] = t;
      }}
复制代码

得到的数据结果如下: (线程数量:10,结果是实验三次取平均)

Dim规模GFLOPS/s(CSR)GB/sTime(s)
5000.0840.440.000063
10000.5052.320.000040
50002.3939.860.000209
100002.59810.550.000770
200002.54410.250.003087
300002.50910.090.007173
400002.4549.850.013037
3.尝试采用三元组进行测试

结果:得到的速度较CSR存储方式的速度要慢,虽然代码设计较CSR简单

4.将部分变量改为unsigned short

结论

1.使用OpenMP中guided进行for循环调度能达到最好的效果。
2. CSR的存储格式较三元组的存储格式更优,访问更快。
3. 采用循环分离等优化方式能够提高GFLOPS的大小。
4. 变量如果提前定义,有可能会得出错误的结果。另外private的调用也会降低GFLOPS的大小

参考

[1]《稀疏矩阵存储格式总结+存储效率对比:COO,CSR,DIA,ELL,HYB》
[2]《稀疏矩阵向量乘法》

代码地址

个人GitHub:Icarusintheworld

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值