主要在vs2015下使用OMP,写一些本身omp的学习心得:学习
1、在VS2015下OpenMP的使用:spa
一、VS2015也仅仅支持OpenMP2.0版本,VS对OpenMP的支持并不太好。线程
二、在VS下使用OPenMP须要在项目设置中找到,项目-->语言-->OpenMP支持中,选择是,下图所示:code
而且在头文件中包含"omp.h"便可支持OpenMP了。blog
2、关于数据属性继承
一、shared 用来声明一个或者多个共享变量,在并行区会有数据竞争。get
二、private 声明私有变量。ast
1 void test_private() 2 { 3 printf("--before parallel--------------\n"); 4 int a =100 ; 5 printf("a=%d\n", a); 6 printf("--parallel--------------\n"); 7 #pragma omp parallel for private(a) 8 for (int i = 0; i < 10; i++) 9 { 10 a = i;//若是a没有被初始化,会提示a没有初始化,即便在并行前作了初始化也会有错误! 11 printf("a=%d\n", a); 12 } 13 printf("--after parallel--------------\n"); 14 printf("a=%d\n", a); 15 }
结果输出:class
--before parallel-------------- a=100 --parallel-------------- a=0 a=6 a=8 a=1 a=2 a=5 a=9 a=3 a=4 a=7 --after parallel-------------- a=100
三、default default(shared):表示并行区域内的共享变量在不指定的状况下都是shared属性;default(none):表示必须显式指定全部共享变量的数据属性,不然会报错,除非变量有明确的属性定义(好比循环并行区域的循环迭代变量只能是私有的。thread
四、firstprivate 继承并行区域以外的变量的值,用于在进入并行区域以前进行一次初始化。
void test_firstprivate() { printf("--before parallel--------------\n"); int a = 100; printf("a=%d\n", a); printf("--parallel--------------\n"); #pragma omp parallel for firstprivate(a) num_threads(3) for (int i = 0; i < 10; i++) { printf("ID=%d,i=%d,a=%d\n",omp_get_thread_num(),i,a); a = i;//对于某个线程来讲,firstprivate仅仅进行一次初始化 } printf("--after parallel--------------\n"); printf("a=%d\n", a); }
结果以下:
--before parallel-------------- a=100 --parallel-------------- ID=0,i=0,a=100 ID=0,i=1,a=0 ID=2,i=7,a=100 ID=0,i=2,a=1 ID=1,i=4,a=100 ID=2,i=8,a=7 ID=0,i=3,a=2 ID=2,i=9,a=8 ID=1,i=5,a=4 ID=1,i=6,a=5 --after parallel-------------- a=100
五、lastprivate 若是须要在并行区域内的私有变量通过计算后,在退出并行区域时,须要将其值赋给同名的共享变量,就能够使用lastprivate完成。
1 void test_lastprivate() 2 { 3 printf("--before parallel--------------\n"); 4 int a = 100; 5 printf("a=%d\n", a); 6 printf("--parallel--------------\n"); 7 #pragma omp parallel for lastprivate(a) num_threads(3) 8 for (int i = 0; i < 10; i++) 9 { 10 a = i; 11 printf("ID=%d,i=%d,a=%d\n", omp_get_thread_num(), i, a); 12 13 } 14 printf("--after parallel--------------\n"); 15 printf("a=%d\n", a); //得到逻辑上a的最后一个值,而不是最后一个线程的a值 16 }
结果以下:
--before parallel-------------- a=100 --parallel-------------- ID=0,i=0,a=0 ID=0,i=1,a=1 ID=1,i=4,a=4 ID=2,i=7,a=7 ID=0,i=2,a=2 ID=2,i=8,a=8 ID=1,i=5,a=5 ID=0,i=3,a=3 ID=1,i=6,a=6 ID=2,i=9,a=9 --after parallel-------------- a=9
六、threadprivate 指定全局变量被OpenMP全部的线程各自产生一个私有的拷贝,即各个线程都有本身私有的全局变量。一个很明显的区别在于,threadprivate并非针对某一个并行区域,而是整个于整个程序,因此,其拷贝的副本变量也是全局的,即在不一样的并行区域之间的同一个线程也是共享的。threadprivate只能用于全局变量或静态变量。
七、copyin 用于将主线程中threadprivate变量的值拷贝到执行并行区域的各个线程的threadprivate变量中,从而使得team内的子线程都拥有和主线程一样的初始值。copyin中的参数必须被声明成threadprivate的。
八、copyprivate用于将线程私有副本变量的值从一个线程广播到执行同一并行区域的其余线程的同一变量。copyprivate只能用于single指令的子句中,在一个single块的结尾处完成广播操做。copyprivate只能用于private/firstprivate或threadprivate修饰的变量。