CPU—OpenMP和GPU—CUDA并行计算技术对矩阵乘法运算的加速效果分析
2017-12-29张岩
张岩
【摘 要】本文对比了CPU-OpenMP和GPU-CUDA并行计算技术对不同阶矩阵乘法运算相对于CPU单线程计算的加速效果。结果表明,CPU-OpenMP并行的计算加速比与矩阵阶数无关,且低于所采用的线程数目。GPU-CUDA并行的计算加速比随矩阵阶数的增加显著增加,最大计算加速比可达570倍以上。相对于CPU单线程计算结果,CPU-OpenMP并行计算未产生误差,而GPU-CUDA并行计算会产生误差。结果表明,GPU-CUDA并行适合高阶数矩阵乘法的加速计算,而CPU-OpenMP并行适合低阶数矩阵乘法的加速计算。
【关键词】矩阵乘法;并行计算;CPU-OpenMP;GPU-CUDA
中图分类号: TP391 文献标识码: A 文章编号: 2095-2457(2017)26-0045-003
Accelerating Effect Analysis of Matrix Multiplication with CPU-OpenMP and GPU-CUDA Parallel Computing
ZHANG Yan
(Beijing Normal University Affiliated High School West High School Class 1, Beijing 100042,China)
【Abstract】This paper compares the accelerating effects of CPU-OpenMP and GPU-CUDA parallel computing on the computation of different-order matrix multiplication over CPU single-thread. The results show that the computational speedup of CPU-OpenMP parallelism is independent of matrix order and lower than the number of threads used. GPU-CUDA parallel computing speedup ratio increases significantly with the increase of the matrix order, the maximum computational speedup up to 570 times. Relative to the CPU single-thread calculations, CPU-OpenMP parallel computing did not produce errors, and GPU-CUDA parallel computing will produce errors. The results show that GPU-CUDA parallel is suitable for accelerated computing of high-order matrix multiplication, while CPU-OpenMP parallel is suitable for accelerated computing of low-order matrix multiplication.
【Key words】Matrix multiplication; Parallel computing; CPU-OpenMP; GPU-CUDA
0 前言
在信息化技術不断发展的今天,人们处在“大数据”时代。由于数据量巨大,普通的串行计算方式计算效率低下,无法满足人们对数据进行快速处理的需求。因此,如何能够提高计算机处理“大数据”的计算效率已成为人们日益关注的话题。为了减少计算时间、提升计算效率,并行计算的出现成为解决上述问题的有效方法。与普通的串行计算相比,并行计算将计算任务分配到计算机的多个处理器协同处理,从而提高计算效率。
随着并行计算结果的发展,并行算法也逐渐成熟。目前,人们采用的并行计算技术大致可能分为两种:一是基于CPU(Central Processing Unit)多核多线程的并行计算;二是基于GPU(Graphics Processing Unit)的通用并行计算。对于CPU并行计算,根据并行粒度的不同可分为“共享式内存结构”和 “分布式内存结构”[1]。对于“共享式内存结构”的并行计算,OpenMP(Open Multi-Processing)作为该类型计算技术的代表,已被广泛应用于数据处理及科学计算中。采用OpenMP做并行计算具有编程简单、源程序改变小等优点[2]。基于GPU的并行计算技术是近年来发展起来的新技术。与基于CPU的并行计算相比,GPU并行计算具有硬件成本低、加速效果显著的优点。随着NVIDIA通用计算架构CUDA(Compute Unified Device Architecture)的提出,人们用GPU做并行计算的编程难度大为降低[3]。
本文旨在采用CPU-OpenMP和GPU-CUDA并行计算技术进行不同阶矩阵的乘法运算,并对比这两种并行计算技术相对于串行计算(CPU单线程)的加速效果。此外,我们也对GPU-CUDA计算所产生的计算误差进行了简要分析。
1 CPU-OpenMP和GPU-CUDA并行计算技术
CPU-OpenMP是一种API(Application Program Interface),用于编写可移植的多线程应用程序,并且无需进行复杂的线程创建、同步、负载平衡和销毁工作。CPU-OpenMP能广泛应用在Windows和Linux等多种平台上,具有可移植性好的优点。在Visual Studio 2010 编程环境下是用OpenMP API时,需打开项目属性里的OpenMP支持选项。CPU-OpenMP的编程实现十分简单,只需在原来串行计算程序里的for循环语句里加入#pragma omp parallel for语句即可实现并行计算[2]。如图1所示,CPU-OpenMP并行计算的思路是主线程将共享内存里的数据分配到不同的分线程里进行计算,各个分线程完成计算任务后将结果返回到主线程,主线程再负责分配各个分线程下一步的计算任务。在CPU-OpenMP代码编写过程中,需对不同线程内的变量属性进行区分,避免不同线程里的私有变量被其他线程的计算修改。endprint
图2是GPU-CUDA的计算架构示意图。GPU-CUDA采用CPU-GPU异构模式协同工作,将CPU称为Host,GPU作为Host的协处理器,即Device。CPU负责串行代码的执行,由GPU负责执行高度并行化的浮点数计算任务。GPU的运算任务被编写在Kernel函数里。如图2所示,每个线程网格(Grid)由多个相同大小和维度的线程块(Block)组成,若干个线程(Thread)又组成了线程块,所以一个Grid就对应了一个Kernel函数。
本研究中CPU单线程和CPU-OpenMP多线程运算的程序代码是用C语言编写的,GPU-CUDA运算的程序代码是用CUDA C编写的。所采用的硬件型号为CPU(Intel Xeon E5-1680 v4, 3.4GHz)和GPU(NVIDIA GeForce GTX1080Ti),操作系统和运行环境为Windows7和Visual Studio 2010,CUDA版本为CUDA 7.0。
2 CPU-OpenMP和GPU-CUDA計算效率对比
首先,随机产生两个n阶方阵An×n和Bn×n,本文中n的取值分别为n=500,1000,2000,4000,8000,矩阵元素类型为float。随后,根据矩阵相乘运算规则计算An×n·Bn×n,即矩阵元素(AB)ij= A B =A B +A B +…+A B ,分别采用CPU单线程、CPU-OpenMP多线程和GPU-CUDA并行技术计算不同阶数矩阵的乘法,统计相应的计算时间,并获得CPU-OpenMP和GPU-CUDA的计算效率加速比。对于GPU-CUDA的计算结果,计算其相对于CPU运算的最大相对误差。本文中,CPU-OpenMP计算线程数和GPU-CUDA计算线程块内的线程数都设置为8。
表1是采用CPU单线程计算不同阶数矩阵乘法所需的计算时间。可以看到,随着矩阵阶数的增加,CPU单线程计算时间明显增加。此外,由于矩阵乘法的计算量是随着矩阵阶数的增加呈指数增加的,采用CPU单线程计算时所需计算时间也是呈指数增加。对于8000阶矩阵乘法,直接采用CPU单线程计算的计算效率已经十分低下,无法满足人们对大通量数据快速处理的要求。
表1 CPU单线程计算不同阶矩阵乘法所需时间
采用CPU-OpenMP多线程并行计算将原来单线程的计算任务分配给多个CPU线程分工执行,从而提高计算效率。表2列出了采用CPU-OpenMP八线程并行计算得到不同阶矩阵乘法所需的计算时间。可以看到,CPU-OpenMP八线程计算时间随着矩阵阶数的增加也呈指数级增加趋势。然而,相对于CPU单线程计算,CPU-OpenMP八线程计算所需的计算时间明显降低。由此可见,采用CPU-OpenMP多线程并行计算可显著提升计算效率。
下面我们采用GPU-CUDA并行技术计算不同阶数的矩阵乘法。首先,在GPU(Device)的显存上为计算矩阵分配内存空间;其次,将CPU(Host)上的矩阵数据复制到GPU显存中,并在GPU上运行Kernel函数进行矩阵乘法运算。在本文所采用的CUDA C程序中,Kernel函数里的内存类型为Global。矩阵乘法计算结束后,把GPU显存上存储的计算结果复制到CPU内存上,释放GPU显存并统计计算时间。表3给出了采用GPU-CUDA并行技术计算不同阶数矩阵相乘的计算时间。与表1和表2 对比可以发现,对于高阶数的矩阵乘法(n >2000),GPU-CUDA所需的计算时间远远低于CPU单线程计算和CPU-OpenMP八线程计算。对于低阶数的矩阵乘法(n =500),GPU-CUDA的计算时间与CPU单核计算时间相差不大,并且慢于CPU-OpenMP八线程计算时间。由此可见,采用GPU-CUDA并行技术对于具有较大的运算量的计算任务具有显著的加速效果,但对于较小运算量的计算任务加速效果不明显。
为了能够更好的展示和比较并行计算的加速效果,图3给出了CPU-OpenMP八线程计算和GPU-CUDA计算相对于CPU单线程的计算加速比。其中,图3(a)的纵坐标用线性表示,图3(b)的纵坐标用指数表示,并且图3(b)上标出了不同阶数矩阵乘法的计算加速比。从图3(a)可以看出,相对于不同阶数的矩阵乘法,CPU-OpenMP八线程计算的加速比变化不大,基本在6左右,低于所采用的线程数目。从图3(b)可以发现,随着矩阵阶数的增加,GPU-CUDA获得的计算加速比显著增大。当矩阵阶数为n=8000时,GPU-CUDA的计算加速比达到了570倍以上,这样的加速效果是相当可观的。
对比CPU单线程计算和CPU-OpenMP多线程并行计算的结果,发现两种计算手段得到的矩阵数据是完全相同的,即CPU-OpenMP多线程并行计算不会产生计算误差。然而,对比发现,采用GPU-CUDA得到的矩阵数据与CPU计算得到的结果有所差异,这可能是由于GPU与CPU 对于float浮点数协议的差异[6]。为了体现GPU-CUDA并行计算所带来的误差,我们对比了GPU-CUDA与CPU对不同阶矩阵乘法的计算结果,并统计了最大相对误差,其计算方式为RE=MAX{[(AB) -(AB) ]/(AB) },计算结果见表4。可以看出,对于低阶数的矩阵乘法(n=500),GPU-CUDA计算得到的矩阵数据误差较大;对于其他阶数的矩阵,GPU-CUDA计算得到的矩阵数据误差较小,甚至为0(n=1000).结合图3(b)给出的计算加速比对比图,可以发现高阶数矩阵乘法的计算更加适合用GPU-CUDA进行加速,此时加速比大且误差较小;低阶数矩阵乘法的计算选用GPU-CUDA加速时需慎重,因为GPU-CUDA可能会给出较大的计算误差。因此,对于低阶数矩阵乘法,宜选用CPU-OpenMP方法进行加速。
3 结论
本文分别采用CPU单线程、CPU-OpenMP多线程和GPU-CUDA并行计算技术,对不同阶数的矩阵乘法进行计算并比较了计算时间。随着矩阵阶数的增加,CPU单线程所需的计算时间成线性增加。对于不同阶数的矩阵乘法,CPU-OpenMP多线程计算都可以加快计算效率,计算加速比低于所采用的线程数目。GPU-CUDA的计算加速比随矩阵阶数的增加显著增加。当矩阵阶数为n=8000时,GPU-CUDA的计算加速比达到了570倍以上。相对于CPU单线程计算结果,CPU-OpenMP的计算结果没有产生误差,而GPU-CUDA计算结果会产生误差。GPU-CUDA的最大相对误差分析表明GPU-CUDA并行计算技术更加适合高阶数的矩阵乘法的加速计算,而CPU-OpenMP更加适合低阶数的矩阵乘法的加速计算。
【参考文献】
[1]唐兵,Laurent BOBELIN,贺海武.基于MPI和OpenMP混合编程的非负矩阵分解并行算法[J].计算机科学,2017,44(03):51-54.
[2]周漫,车欣.大规模稠密线性方程组求解的并行计算方法[J].信息与电脑(理论版),2016(11):88-89.
[3]周海芳,高畅,方民权.基于CUBLAS和CUDA的MNF并行算法设计与优化[J].湖南大学学报(自然科学版),2017,44(04):147-156.
[4]Blaise Barney,OpenMP tutorials [M]:https://computing.llnl.gov/tutorials/openMP/.
[5]NVIDIA,CUDA C programming guide[M].NVIDIA Corporation,2015:11.
[6]迟学斌,王彦棢,王珏,刘芳.并行计算与实现技术[M]. 北京:科学出版社,2015.endprint