欢迎光临散文网 会员登陆 & 注册

自编教材分享:第九章—OpenMP编程简介

2023-11-24 09:16 作者:先进编译实验室  | 我要投稿


OpenMP是什么

OpenMP是一种用于共享内存并行编程的多线程程序设计方案,适合在共享内存编程下的多核系统上进行并行程序设计。程序员在完成程序功能开发的基础上,只需添加指导语句#pragma即可自动将串行执行转换为并行处理,当编译器不支持OpenMP时,程序会忽略#pragma语句,按照串行顺序执行。OpenMP的使用降低了多核并行编程的难度,优化人员可以更多地考虑算法本身,而非具体的并行实现细节。

Fork-Join模式:在并行区的开始位置建立多个线程,在并行区的结束位置自动合并线程,具体执行方式为在串行区由主线程执行代码,当程序由串行区进入并行区后,主线程和派生出来的子线程共同执行并行区内的代码,当并行区代码全部执行完毕后合并子线程,由主线程继续执行位于并行区后的串行区代码。

SPMD模式:在单个并行程序中按照线程号来匹配程序分支,不同线程分配不同的计算任务。在此模式下,整个线程组仅需一次创建和一次合并。并行执行程序中的循环时,各线程分别执行整个循环迭代的一部分,当迭代之间存在依赖关系时可以通过插入同步语句、线程间近邻通信以及流水并行来维持正确性,此执行模式下线程的控制开销较小且程序性能较高。

OpenMP程序由指导语句、库函数和环境变量三部分组成。其中,指导语句是串行程序实现并行化的桥梁,是编写OpenMP程序的关键。库函数的作用是在程序运行阶段改变和优化并行环境从而控制程序的运行。环境变量是库函数中控制函数运行的一些具体参数。

OpenMP指导语句

指导语句中#pragma omp标识符是固定前缀,parallel for为指导命令,每条指导语句只能有一个指导命令。这里的parallel for是OpenMP规范中定义的复合指导命令,在指导命令parallel for之后的是与之配套的子句,功能是为并行区开启4个线程和指定变量的属性,除非有另外的限制,否则子句能够按照任意顺序进行排列。需要注意的是子句是可选项,有些指导命令没有配套子句。续行符同样也是可选项,表示指导语句还未结束需要在下一行中继续,可用于语句长度超过一行时的逻辑分割。最后加入换行符表明指导语句终止。

指导语句中的指导命令按照功能可分为并行控制类型、工作共享类型、线程同步类型和复合指导命令类型。并行控制类型指导命令的功能是构建并行区,并创建线程组来并行执行计算任务;工作共享类型指导命令的功能是将任务分配给各线程,工作共享指导命令不能创建新的线程,且必须位于并行区中;线程同步类型指导命令的功能是利用互斥锁和事件通知的机制来控制线程的执行顺序,保证执行结果的正确性。此外,OpenMP还提供了不同类型指导命令组成的复合指导命令。

并行控制类:parallel、simd

工作共享类:for、sections、task、single、target

线程同步类:barrier、master、critical、atomic、flush、ordered

复合指导命令类:parallel for、for simd、parallel sections

parallel和for是OpenMP程序编写过程中最常用的指导命令,指导命令parallel在当前大括号修饰区域内创建一组指定数量的线程,构建一个并行区,并为跨越串行区和并行区的同名变量配置属性,一般与for、sections等指导命令配合使用。当线程执行到parallel指导语句时会创建一个线程组并成为这个线程组中的主线程,线程组内线程数量由环境变量或运行时库决定。需要注意的是,一个并行区必须是一个连续的结构,即不能跨越多个程序或者代码文件。

for指导语句用来对循环结构进行并行处理,将循环的迭代计数器在线程组中进行共享以完成数据的并行,实现并行的前提是此循环结构已位于parallel指导语句构建的并行区内,否则以串行的方式执行。

指导命令for与parallel可以组合为parallel for复合指导命令,parallel指导语句的功能是创建多个线程来分别执行相同的任务,而parallel for指导语句必须使用在循环结构前,其功能是在构建并行区后将循环执行的任务在多个线程之间分配,让每一个线程各自负责其中的一部分循环迭代任务。

parallel 指导语句

for 指导语句

在将串行程序改为并行程序时,需要针对程序中的热点问题即程序中耗时较多的代码段进行改写才能得到较大的加速收益,典型的热点代码段为循环结构,可以利用第三章中的程序性能测量工具查找程序中的耗时较多部分。经测试,发现代码9-3中矩阵乘法程序的热点代码段为三层循环嵌套,因此对该部分添加parallel for复合指导语句进行并行化改写。

矩阵乘法程序中核心代码共有三层循环嵌套,但并不是每层循环都可以添加并行指导语句parallel for达到程序加速的效果,如将指导语句parallel for添加在最内层循环,则会带来程序正确性的问题,因为最内层循环负责将矩阵A第i行的元素与对应矩阵B第j列的元素相乘后累加得到C[i][j],若将最内层并行会将这一计算任务分配给多个线程并行执行,每个线程仅执行部分行列乘积的累加,由于线程间执行速度的不同会引发对C[i][j]的读写冲突,最终导致C[i][j]的结果错误。这里可以将并行指导语句添加至第二层或最外层循环,这里先添加至第二层循环。


自编教材分享:第九章—OpenMP编程简介的评论 (共 条)

分享到微博请遵守国家法律