openMP---第二篇

1、for循环嵌套

// 首先确保循环之间没有数据依赖, 尽量在外部使用
int a=0;  
int b=0;  
void openmpTest1(int thread_num)  
{   

    #pragma omp parallel for num_threads(thread_num)  
    for(int i=0;i<1000000000;i++)  
    {  

     for(int j=0;j<1000000000;j++)  
      {  
        a++;  
       }  

     for(int j=0;j<1000000000;j++)  
       {  
        b++;  
       }  
    }  
}  

不要在每个for循环 都加上parallel for,openmp 的线程调度也很大,性能会变得很差。

2、#pragma omp parallel for schedule(static,4)

schedule(kind [, chunk_size]),其中kind可以取值为static,dynamic,guided等。

对于schedule(static,size)的含义,OpenMP会给每个线程分配size次迭代计算。这个分配是静态的,“静态”体现在这个分配过程跟实际的运行是无关的,可以从逻辑上推断出哪几次迭代会在哪几个线程上运行

对于dynamic,没有size参数的情况下,每个线程按先执行完先分配的方式执行1次循环,比如,刚开始,线程1先启动,那么会为线程1分配一次循环开始去执行(i=0的迭代),然后,可能线程2启动了,那么为线程2分配一次循环去执行(i=1的迭代),假设这时候线程0和线程3没有启动,而线程1的迭代已经执行完,可能会继续为线程1分配一次迭代,如果线程0或3先启动了,可能会为之分配一次迭代,直到把所有的迭代分配完。

#include <omp.h>
#include <Windows.h>

#define COUNT 4*3

int main(int argc, _TCHAR* argv[])  
{

       #pragma omp parallel for schedule(dynamic)
    for(int i = 0;i < COUNT; i++) 
    {
        printf("Thread: %d, Iteration: %d\n", omp_get_thread_num(), i);
    }

    return 0;  
}

guided调度

类似于动态调度,但每次分配的循环次数不同,开始比较大,以后逐渐减小。size表示每次分配的迭代次数的最小值,由于每次分配的迭代次数会逐渐减少,较少到size时,将不再减少。如果不知道size的大小,那么默认size为1,即一直减少到1。

3、private:指定一个或多个变量在每个线程中都有它自己的私有副本

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

private、firstprivate、lastprivate:用于表示并行区域内的变量的数据范围属性。其中,private表示并行区域team内的每一个线程都会产生一个并行区域外同名变量的共享变量,且和共享变量没有任何关联;firstprivaet在private的基础上,在进入并行区域时(或说每个线程创建时,或副本变量构造时),会使用并行区域外的共享变量进行一次初始化工作;lastprivate在private的基础上,在退出并行区域时,会使用并行区域内的副本的变量,对共享变量进行赋值,由于有多个副本,OpenMP规定了如何确定使用哪个副本进行赋值。另外,private不能和firstprivate/lastprivate混用于同一个变量,firstprivate和lastprivate可以对同一变量使用,效果为两者的结合。

如果对于子句理解不好,尽量避免使用。

参考:OpenMP 中的线程任务调度   

https://www.cnblogs.com/Allen-rg/p/10746092.html  

posted @ 2020-06-04 14:19  玥茹苟  阅读(201)  评论(0编辑  收藏  举报