基于OpenMP并行编程模型与性能优化的稀疏矩阵操作研究
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于OpenMP并行编程模型与性能优化的稀疏矩阵操作研究
作者:蔡文海陈洺均
来源:《软件导刊》2016年第03期
摘要:随着多核处理器的普及,传统的串行编程方式已无法充分利用多核处理器资源,业界提出了用并行编程模型解决此类问题的多种方法,OpenMP便是其中一种。
OpenMP并行编程模型提供了一种可以通过编译语句对现有串行程序进行并行化运行的方法,提高了现有程序对计算机处理器的利用率。
基于OpenMP探讨大型稀疏矩阵转置分别在串行编程模型与并行编程模型中计算机处理器的利用率,针对矩阵转置中数据相关性进行加锁操作,通过实验数据分析总结OpenMP并行编程模型的设计方案。
关键词:OpenMP;并行编程;稀疏矩阵
中图分类号:TP302 文献标识码:A 文章编号:1672-7800(2016)003-0027-02
作者简介:蔡文海(1992-),男,广西北海人,桂林电子科技大学信息科技学院学生,研究方向为高性能计算;陈洺均(1982-),女,四川巴中人,硕士,桂林医学院信息中心讲师,研究方向为数据库、高性能计算。
0 引言
传统串行编程模型已经无法实现多核处理器资源利用最大化[1]。
OpenMP作为并行编程模型的解决方案,逐渐成为工业标准[2]。
如何将OpenMP更好地应用到编程中解决多核处理器资源利用最大化问题,成为一个重要的研究课题。
1 串行编程模型与并行编程模型-OpenMP
传统串行编程模型下,程序线路自始至终是唯一的。
即使使用多核处理器,程序依然只能利用单个核进行运算,这样势必造成其它处理器闲置,无法发挥多核处理器的性能。
OpenMP 的提出为解决这一问题提供了方案,其作为最早提出的并行编程模型,逐渐成为并行编程的规范[3]。
OpenMP是面向共享内存以及分布式共享内存的多处理器多线程并行编程语言[4],是一种编译指导语句,能够显式地指导多线程、共享内存并行的应用程序编程接口(API),具有良好的可移植性,支持多种编程语言,如Fortran、C、C++。
OpenMP以线程为基础,通过编译指导语句显式执行并行化,提供并行化的完整控制。
众所周知,Java语言也内置了对多线程的支持,然而Java中的多线程并不能完成计算机多个处理器同时处理。
因为Java虚拟机采用时间片轮转的方式,根据计算机给定的时间段执行线
程,该时间片结束后,Java虚拟机会迅速切换到另一个线程继续运行,整个过程中,Java多线程交叉串行运行。
与Java多线程不同,当线程数量小于或等于处理器数量时,OpenMP每一个线程都拥有自己的处理器并进行运算,大大提高了处理器的利用率。
OpenMP采用Fork-Join 执行模式,如图1所示。
(1)开始执行时,只有主线程运行。
(2)在主线程运行过程中,需要进行并行计算时,派生出(Fork,创建新线程或者唤醒已有线程)线程来执行并行任务。
(3)执行并行时,主线程和派生线程同时工作。
(4)并行代码执行结束后,派生线程退出或者挂起,不再工作,控制流程回到单独的主线程中(Join,即多线程的汇合)。
2 大型稀疏矩阵转置
在微分方程数值解法中,线性代数方程组系数矩阵系数往往很高,但其非零元素所占的比重很小,将这种矩阵称为大型稀疏矩阵。
大型稀疏矩阵转置数据运算量大,可以用一个三元组确定一个唯一矩阵元素,这个三元组分别表示非零元素的行号、列号和值。
所有三元组构成一个三元组表,该三元组表是一个线性表[5]。
传统的串行编程算法中,假设存在待转置的稀疏矩阵M,首先找出矩阵M第i列所有元素,并转置,将结果存放到转置后矩阵N的第i行;再找出矩阵M的第i+1列的所有元素,并转置,将结果存放到矩阵N的第i+1行;依次执行,直到所有元素转置完毕。
3 并行优化
上述算法每一列转置运算都是独立的,假设运算程序的计算机为X(X>1)核处理器,若使用上述算法运算,将浪费X-1个处理器资源。
本文设计优化思想为将每一列的矩阵转置运算分离出来,每一次使用X个处理器进行处理,实现计算机处理器利用率最大化[6]。
在实际设计与实现过程中,使用三元组实现大型矩阵存储,对三元组存储进行了压缩,使得在对三元组存储的矩阵进行转置时,需要使用第三变量作为连接进行转置。
当使用OpenMP 进行并行编程时,这个第三变量在转置运算中与其它三元组有数据相关性的。
需要对该变量进行特殊的加锁操作,保证变量的唯一性,使程序正确运行,但该操作将对程序并行效率产生一定影响。
本文以多个数量级稀疏矩阵为对象(包括100K、1M、10M),横向研究同数量级的稀疏矩阵中,串行编程及基于OpenMP并行编程的计算机运算效率;纵向研究不同数量级运算量在
基于OpenMP并行编程的计算机中的运算效率,进行纵向对比。
研究基于OpenMP并行模型优化且进行加锁后,程序核心算法流程如图2所示。
理论情况下,双线程算法耗费时间应为普通算法的50%,而四线程算法耗时应为普通算法的25%,是双线程算法耗时的50%。
实际操作中,100K数据量下,普通算法平均耗时为427.6ms;基于OpenMP优化后,双线程算法耗时为230.8ms,四线程算法为165.4ms,如图3所示。
双线程算法耗时为普通算法的53.98%,接近理论值,而4线程耗时为普通算法的
38.68%,是双线程算法的71.66%,与理论值相差较大。
当数据量较小时,线程创建及销毁需要一定时间开销,四线程时间开销相对较大,导致计算机运行效率提高相对较低。
在1M数据下,普通算法平均耗时为10730.2ms;基于OpenMP优化后,双线程算法为6910.6ms,四线程算法为3856.2ms,如图4所示。
双线程算法耗时为普通算法的64.40%,双线程算法运行效率降低;而四线耗时为普通算法的35.93%,是双线程算法的55.80%。
可以看出,当数据量达到一定大小时,线程创建等时间开销相对于运算处理时间微乎其微,线程数量越接近处理器核心数量,计算机运行效率越高。
在10M数据下,普通算法平均耗时为1785476.4ms;基于OpenMP优化后,双线程算法为1027152.6ms,四线程算法为633355.8ms,如图5所示。
双线程算法号时为普通算法的
57.52%,双线程算法在更大数据量中运行效率在降低;而四线程耗时普通算法的35.47%,是双线程算法的61.66%,当数据量达到一定大小时,线程开销可忽略不计。
然而,由于数据相关性、一致性及同步性等原则,代码优化中对部分代码进行了加锁,当有线程在加锁部分运行时,其它线程不可进入,直到加锁部分执行结束,需要计算其它线程等待的时间,因此四线程并不能达到理论值或接近理论值。
4 结语
基于Open的并行编程模型并非简单地将线程最大化,需要考虑代码上下变量间以及函数间是否具有数据相关性、同步性及内存一致性等[7]。
OpenMP在大数据运算中可以提高计算机的运行效率,然而并非线程越多越好,因为线程创建及启动需要一定时间开销;当创建线程等开销时间大于运算时间时,反而使得计算机运行效率降低;数据量越大,OpenMP越能提高计算机的运行效率,并且越稳定,此时若线程数分配至与计算机核心数一致,可实现计算机运行效率最大化[8]。
OpenMP在大数据并行编程中有明显优势,然而OpenMP并不能很好地满足普通编程的需要,如果将来普及为常用并行编程模型,需要对小数据量并行编程进行优化,对线程创建等开销进行优化。
参考文献:
[1] 周伟明. 多核计算与程序设计[M].武汉:华中科技大学出版社,2009.
[2] 罗秋明. OpenMP编译原理及实现技术[M].北京:清华大学出版社,2012.
[3] 赵辉,王振夺. 基于OpenMP的多核系统中并行优化研究[J].北华航天工业学院学报,2014(12):16-19.
[4] 高瑛,严正国. OpenMP多核并行程序的设计与实现[J].电子测试,2014(5):30-35.
[5] 张乃孝. 算法与数据结构 [M]. 北京:高等教育出版社,2009.
[6] 孙洪迪,高柱. 基于OpenMP技术的多核处理器程序的开发实现[J].北京工业职业技术学院学报,2010(1):10-15.
[7] ROHIT CHANDRA.Parallel programming in OpenMP[M].Morgan Kaufmann,2012.
[8] OpenMP application program interface version 4.0.0[EB/OL].http://.
(责任编辑:陈福时)。