主要在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修飾的變量。