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、#
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可以对同一变量使用,效果为两者的结合。
如果对于子句理解不好,尽量避免使用。
https://www.cnblogs.com/Allen-rg/p/10746092.html