OpenMP命令与子句

时间:2021-12-01 04:35:26

  1、为了在OpenMP中创建线程,需要指定一些代码块并行地运行,C/C++中可以通过指定#pragma omp parallel完成.

    2、OpenMP要求I/O库是线程级安全的,但它并没有指定哪一个线程在什么时间打印它的记录,因此输出记录的任何有效交错都有可能发生,程序员不能依靠线程以一种特定的顺序打印它们的记录.

    3、如果在一个并行区域中声明一个变量,则对于一个线程来说,它是局部的或私有的。在C语言中,变量声明可以出现在任何块中;但在FORTRAN中,声明仅能够出现在子程序的开始部位.

    4、为了创建一个具有num_threads个线程的并行区域,可以使用指令:#pragma omp parallel num_threads.

    5、当单独使用并行构造时,每个线程执行相同的语句块。但有时候,我们需要不同的代码被映射到不同的线程中,这称为工作分摊法(worksharing).在OpenMP中,最常用的工作分摊法构造是在不同的线程间划分循环迭代的构造.

    6、OpenMP规范认为,在一个并行循环*享循环控制索引是不可行的,因此系统为每个线程自动创建循环控制索引的一个私有副本.

    7、 schedule(static)子句将并行循环的迭代分解为多个连续的块,每一个块的大小近似相等,每一个线程处理一个块。这种调试对于实现几何分解模式的循环并行程序来说,是非常重要的.static对应的还有dynamic, guided, runtime.

    8、single构造定义了一个代码段,该代码段将被第一个利用该构造的线程执行.

    9、通过使用omp parallel for指令,很容易完成循环的并行化。这个指令告诉编译器创建一队线程,并在这些线程间划分循环的迭代。使用模式的最常见错误是魅力了"私有"关键变量,编译器通常不检测这些错误.

 10、利用flush语句定义存储器围栅:#pragma omp flush 这个语句使得它们被在计算机的存储器中更新,是一个开销昂贵的操作,因为保证一致性需要某些缓存行、所有的系统缓冲区和寄存器被写到存储器中。存在一种开销较低的版本,列举即将被flush的变量:#pragma omp flush (flag)

    11、默认情况下,OpenMP自动地在工作分摊(worksharing)结构(for, single, section等)的结尾处插入栅栏,即所有的线程在该构造的结尾处等待,直至所有的线程都到达该点,才继续向后执行。如果需要,可以使用nowait子句关闭这种隐式栅栏:#pragma omp for nowait.

    12、#pragma omp parallel reduction (+:  sum) ,在parallel指令中使用了一个reduction子句,以表明将对变量sum做一个+运算归约。编译器将创建该变量的一个局部副本,并将它初始化为问题是运行的特征值(identity value)(对于加法来说,是0)。每个线程将它的值的总和放到这个局部副本中。在并行区域后面,所有的局部副本被组合进全局副本,以产生最终值.

    13、private(list)子句指示编译器在每个线程中为列表中所包含的每个名称创建一个私有(或局部)变量.私有列表中的名称必须已经被定义.如:#pragma omp parallel for private(h)

    14、OpenMP中主要的同步构造:flush ,critical, barrier.

    15、#pragma omp parallel for 这条语句是用来指定后面的for循环语句变成并行执行的,当然for循环里的内容必须满足可以并行执行,即每次循环互不相干,后一次循环不依赖于前面的循环。

    16、OpenMP的指令有以下一些:

parallel,用在一个代码段之前,表示这段代码将被多个线程并行执行

for,用于for循环之前,将循环分配到多个线程中并行执行,必须保证每次循环之间无相关性。
parallel for, parallel 和 for语句的结合,也是用在一个for循环之前,表示for循环的代码将被多个线程并行执行。
sections,用在可能会被并行执行的代码段之前
parallel sections,parallel和sections两个语句的结合
critical,用在一段代码临界区之前
single,用在一段只被单个线程执行的代码段之前,表示后面的代码段将被单线程执行。

flush,

barrier,用于并行区内代码的线程同步,所有线程执行到barrier时要停止,直到所有线程都执行到barrier时才继续往下执行。
atomic,用于指定一块内存区域被制动更新
master,用于指定一段代码块由主线程执行
ordered, 用于指定并行区域的循环按顺序执行

threadprivate, 用于指定一个变量(全局变量或者本地静态变量)是线程私有的。

OpenMP除上述指令外,还有一些库函数,下面列出几个常用的库函数:
       omp_get_num_procs, 返回运行本线程的多处理机的处理器个数
       omp_get_num_threads, 返回当前并行区域中的活动线程个数
       omp_get_thread_num, 返回线程号
       omp_set_num_threads, 设置并行执行代码时的线程个数

omp_init_lock, 初始化一个简单锁

omp_set_lock, 上锁操作

omp_unset_lock, 解锁操作,要和omp_set_lock函数配对使用。

omp_destroy_lock, omp_init_lock函数的配对操作函数,关闭一个锁

OpenMP的子句有以下一些

private, 指定每个线程都有它自己的变量私有副本.

firstprivate,指定每个线程都有它自己的变量私有副本,并且变量要被继承主线程中的初值.

lastprivate,主要是用来指定将线程中的私有变量的值在并行处理结束后复制回主线程中的对应变量.

reduce,用来指定一个或多个变量是私有的,并且在并行处理结束后这些变量要执行指定的运算.

nowait,忽略指定中暗含的等待

num_threads,指定线程的个数

schedule,指定如何调度for循环迭代

shared,指定一个或多个变量为多个线程间的共享变量

ordered,用来指定for循环的执行要按顺序执行

copyprivate,用于single指令中的指定变量为多个线程的共享变量

copyin,用来指定一个threadprivate的变量的值要用主线程的值进行初始化.

default,用来指定并行处理区域内的变量的使用方式,缺省是share

    17、for指令要和parallel指令结合起来使用才有效果.

    18、section语句是用在sections语句里用来将sections语句里的代码划分成几个不同的段,每段都并行执行.