OpenMP的基本要素:
1. 编译指导指令(Compiler Directive)
在C/C++程序中,OpenMP的编译指导指令以 #pragma omp开始
例如: #pargma omp 指令 [子句[, 子句]……]
子句的类型:
1. 并行域控制类
2. 任务分担类
3. 同步控制类
4. 数据环境类
2. 运行库函数 (Runtime Library)
3. 环境变量(Environment Variables)
OpenMP的执行模型是fork-join.
并行域(Paralle region):在成对的fork和join之间的域。
OpenMP规范中的指令:
* parallel:用在一个结构快之前,表示这段代码将被多线程并行执行。
* for:用于for循环语句之前,标识将循环任务计算分配到多线程中并行执行,以实现任务分担,必须由编程人员自己保证每次循环之间无数据相关性。
* parallel for:parallel和for执行的结合,也是用在for循环语句之前,表示for循环体的代码将被多线程并行执行,它同于具有并行域和产生分担两个功能。
* sections:用在可被并行执行代码之前,用于实现多个结构块语句在任务分担,可并行执行的代码段各自用section执行标出(注意区分sections和sction)。
* parallel sections:parallel和sections两个语句的结合,类似于parallel for。
* single:用在并行域内,标识一段只被单线程执行的代码。
* critical:用在一段代码临界区之前,保证每次只有一个OpenMP线程进入。
* flush:保证各个OpenMP线程的数据影像的一致性。
* barrier:用于并行域内代码的线程同步,线程执行到barrier时要停下等待,知道所有线程都执行到barrier时才继续往下执行。
* atomic:用于指定一个数据操作需要原子性的完成。
* master:用于指定一段代码由主线程执行。
* threadprivate:用于执行一个或多个变量是线程专用。
OpenMP规范中的子句:
* private:指定一个或多个变量在每个线程中都有它自己的私有副本。
* firstprivate:指定一个或多个变量在每个线程都有它自己的副本,并且私有变量要在进入并行域或任务分担域时,继承主线程中的通名变量的值作为初值。
* lastprivate:是用来指定将线程中一个或多个私有变量在并行处理结束后复制到主线程的同名变量中,负责拷贝的线程是for或sections任务分担中的最后一个线程。
* reduction:用来指定一个或多个变量是私有的,并且在并行处理结束后这些变量要执行指定的归约运算,并将结果返回给主线程同名变量。
* nowait:指出并发线程可以忽略其他指导指令暗含的路障同步。
* num_threads:指定并行域内的线程数目。
* schedule:指定for任务分担中任务分配调度类型。
* shared:指定一个或多个变量为多线程间的共享变量。
* ordered:用来指定for任务分担域内指定代码段需要按照串行循环次序执行。
* copyprivate:配合single指令,将指定线程的专有变量广播到并行域内其他线程的同名变量中。
* copyin:用来指定一个threadprivate类型的变量需要用主线程同名变量进行初始化。
* defalut:用来指定并行域内的变量使用方式,缺省是shared。
OpenMP规范中API函数:
omp_in_parallel:判断当前是否在并行域中
omp_get_thread_num:返回线程号
omp_set_num_threads:设置后续并行域中的线程个数
omp_get_num_threads:返回当前并行域中的线程数
omp_get_max_threads:获取并行域可用的最大线程数
omp_get_num_procs:返回系统中处理器个数
omp_get_dynamic:判断是否支持动态改变线程数目
omp_set_dynamic:启用或关闭线程数目的动态改变
omp_get_nested:判断系统是否支持并行嵌套
omp_set_nested:启动或关闭并行嵌套
omp_init(_nest)_lock:初始化一个(嵌套)锁
omp_destroy(_nest)_lock:销毁一个(嵌套)锁
omp_set(_nest)_lock:(嵌套)加锁操作
omp_unset(_nest)_lock:(嵌套)解锁操作
omp_test(_nest)_lock:非阻塞(嵌套)加锁
omp_get_wtime:获取wall time时间
omp_set_wtime:设置wall time时间
OpenMP规范中环境变量:
OMP_SCHEDULE:用于for循环并行化后的调度,它的值就是循环调度类型
OMP_NUM_THREADS:用于设置并行域中的线程数
OMP_DYNAMIC:通过设定变量值,来确定是否允许动态设定并行域内的线程数
OMP_NESTED:指出是否可以并行嵌套
OpenMP规范中ICV:
一些内部控制变量ICV(internal control variable)用于标识系统的属性、能力和状态等。可以通过OpenMP API函数访问也可以通过环境变量进行修改。但是变量的具体名字和实现方式可以由各个编译器自行决定。