OpenMP学习笔记

一、什么是openMP

OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C、C++和Fortran。OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的并行程序设计。编译器根据程序中添加的pragma指令,自动将程序并行处理,使用OpenMP降低了并行编程的难度和复杂度。当编译器不支持OpenMP时,程序会退化成普通(串行)程序。程序中已有的OpenMP指令不会影响程序的正常编译运行。

二、openMP的执行模式

OpenMP采用fork-join的执行模式。开始的时候只存在一个主线程,当需要进行并行计算的时候,派生出若干个分支线程来执行并行任务。当并行代码执行完成之后,分支线程会合,并把控制流程交给单独的主线程。

OpenMP学习笔记_第1张图片

 三、基本语法与指令

需要include头文件

基本格式

#pragma omp 指令 [子句1] [子句2] [子句3] ...

指令必选,决定该编译指令的作用
子句可选,控制变量的访问、初始化、共享等。
区分大小写。
遵循编译指令的C/C++规则。
通过在指令行末尾用反斜杠(“\”)转义换行符,可以在后续行上“继续”长指令行
每个指令最多使用一个后续子句,该子句必须是结构化块

常用指令

parallel:创建线程组 + 并行执行
for : 将for循环分配给各个线程并行化执行,循环变量只能是整型。
sections : 非迭代式共享任务并行化
single : 代码段由一个线程执行(不一定是主线程)
atomic : 指定的内存某位置被原子更新
barrier : 实现所有线程同步
critical :创建临界区,线程互斥访问
flush : 所有线程对所有共享对象具有相同的内存视图。当并行区域里存在一共享变量,并且对其进行修改时,需要用flush更新变量,确保并行的多线程对共享变量的读操作是最新值。共享的语句一般都隐含了flush。
master :指定由主线程来运行接下来的程序
ordered :指定在接下来的代码块中,被并行化的 for循环将依序运行
threadprivate :指定一个变量是线程局部存储

常用子句

private :其列出来的变量对于线程私有
firstprivate : private的功能 + 对于线程局部存储的变量,其初值是进入并行区之前的值
lastprivate : private的功能 + 并行区里的值在最后会赋值给并行区前面的变量。
default :自定义一个并行区的默认的变量的作用范围
shared :其列出来的变量对于所有线程共享
reduction : 对于各个线程私有的变量,在并行区结束时通过某种运算归一。
schedule : 线程调度,有 dynamic、guided、runtime、static 四种方法。
ordered :将for循环按照顺序执行
num_threads : 设置线程数量的数量。默认值为当前计算机硬件支持的最大并发数。
nowait :忽略barrier的同步等待。
if : 决定是否并行化
copyin :控制变量在串行和并行部分传递,让threadprivate的变量的初始值和主线程的值相同。copyin中的参数必须被声明成threadprivate。
copyprivate :不同线程中的变量在所有线程中共享。copyprivate只能用于single指令的子句中,在一个single块的结尾处完成广播操作。copyprivate只能用于private/firstprivate或threadprivate修饰的变量。

四、openMP编程

#include 
#include 

void main () {
    #pragma omp parallel 
    {
        int ID = omp_get_thread_num();

        printf("HelloWorld! My threadID is %d\n", ID);    
    }
}

编写完成后,需要设置线程数,这里我设置为4个线程

设置线程数:export OMP_NUM_THREADS=4

第一次运行结果:

OpenMP学习笔记_第2张图片

第二次运行结果:

OpenMP学习笔记_第3张图片

可以看出,使用openMP编程时,所有线程都会执行并行区内部的代码,且每个线程的执行顺序是随机的。

你可能感兴趣的:(学习)