说明:
1.转载请联系本人
2.代码在最后实验目标
通过编写OpenMp版本的矩阵乘法(SGEMM)熟悉OpenMP编程模型,鼓励尝试不同的优化策略。
问题描述
在数学领域中,矩阵乘法将两个矩阵进行相乘,得出另一个矩阵。
矩阵乘法在实际应用中有广泛的使用,并被不同的编程语言所实现。1979年制定的基础线性代数子程序标准(BLAS)描述了基本的线性代数运算,包括矩阵乘法。
BLAS分为三个级别,而矩阵-矩阵运算属于第三级。 下式中,a、b为常数,A、B、C为矩阵。
C = aAB + bC
实验要求
- 根据内存大小测不同规模矩阵的处理速度(GFLOPS/s),并给出计算公式
- 请计算系统的理论峰值,如果没有达到理论峰值,尝试给出原因
解决思路与方法
1.实现OpenMP下的普通版本的矩阵相乘:
用OpenMP编写两个n阶的方阵A和B的相乘程序,结果存放在方阵C中,其中乘法用for编译制导语句实现并行化操作,并调节for编译制导中schedule的参数,使得执行时间最短
使用num_threads()函数指定并行线程数
2.优化版:
1)利用矩阵分块
将矩阵乘法的计算转化为其各自分块矩阵相乘而后相加,能够有效减少乘数矩阵和被乘数矩阵调入内存的次数,可加快程序执行。
2)用一维数组表示二维
二维数组在内存中也是一维数组,但是可以通过转换的公式,减少实际的乘法次数,以达到优化效果
注:分块和一维表示不能同时进行。
(同时进行会报错,可能是涉及到分块的问题,一维的位置规则和分块的位置不太一样)
实验
1.实验环境
本机: CPU:i5-4210U 内存:8G OS: Windows10 1607
实验室:CPU: i7-7700K GPU:GTX 1080 内存:8G DDR4 OS:Ubuntu 16.04
2.结果及分析
不同规模矩阵处理速度公式:
Speed = 2*N^3/time Gflops
(对结果矩阵C分析知,每个循环进行一次加和乘操作)GPU理想值:单精度浮点运算运算能力是9Tflops 一个TFLOPS(teraFLOPS)等于每秒一万亿(=10^12)次的浮点运算
时间/s | 256 | 512 | 1024 | 2048 |
---|---|---|---|---|
本地 | 0.37 | 3.72 | 50.81 | / |
GPU | 0.049 | 0.47 | 3.68 | 104.3 |
GPU(时间/s) | 256 | 512 | 1024 | 2048 |
---|---|---|---|---|
分块 | 0.046 | 0.46 | 3.75 | 29.9 |
一维数组 | 0.019 | 0.364 | 2.91 | 82.1 |
注:每个时间是运行三次取平均值的结果(线程数量均为64)
P.S Max=2048下线程数量从64换到256,时间上没有任何的进步……
结论
在GPU环境下,矩阵相乘的运行速度明显提高,但在维度较大的情况下,对代码进行优化会有更好的效果。
代码地址
个人GitHub:Icarusintheworld