(一)、openMP簡述
- Open Multiprocessing (OpenMP) 框架是一種功能極為強大的規范,可以幫助您利用 C、C++ 和 Fortran 應用程序中的多個核心帶來的好處,是基於共享內存模式的一種並行編程模型, 使用十分方便, 只需要串行程序中加入OpenMP預處理指令, 就可以實現串行程序的並行化。
(二)、openMP簡單使用
1、簡單的HelloWord程序
-
#include <iostream> int main() { #pragma omp parallel { std::cout << "Hello World!\n"; } }
#pragma omp parallel
僅在您指定了-fopenmp
編譯器選項后才會發揮作用。在編譯期間,GCC 會根據硬件和操作系統配置在運行時生成代碼,創建盡可能多的線程。- 只運行 g++ hello.cpp,只會打印出一行Hello world!
- 運行g++ hello.cpp -fopenmp,打印出12個Hello World!(12個是因為我用的是linux服務器默認分配的)
- 運行結果
-
user@NLP ~/vsworksapce $ g++ hello.cpp user@NLP ~/vsworksapce $ ./a.out Hello World! user@NLP ~/vsworksapce $ g++ hello.cpp -fopenmp user@NLP ~/vsworksapce $ ./a.out Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!
2、如何自定義線程數量
- num_threads的設置
- omp_set_num_threads()庫函數的設置
-
#include <omp.h> #include <iostream> int main() { int number_threads = 1; omp_set_num_threads(number_threads) //方法二 #pragma omp parallel num_threads(number_threads) //方式一 { std::cout << "Hello World!\n"; } }
- OMP_NUM_THREADS環境變量的設置 (Linux下:export OMP_NUM_THREADS=4)
- 編譯器默認實現(一般而言,不指定具體線程數量的情況下,默認實現的總線程數等於處理器的核心數)
3、parallel sections 編譯指示
pragma omp sections
和pragma omp parallel
之間的代碼將由所有線程並行運行。pragma omp sections
之后的代碼塊通過pragma omp section
進一步被分為各個子區段。每個pragma omp section
塊將由一個單獨的線程執行。但是,區段塊中的各個指令始終按順序運行。
-
#include <iostream> int main() { #pragma omp parallel { std::cout << "parallel \n"; #pragma omp sections { #pragma omp section { std::cout << "section1 \n"; } #pragma omp section { std::cout << "sectio2 \n"; std::cout << "after sectio2 \n"; } #pragma omp section { std::cout << "sectio3 \n"; std::cout << "after sectio3 \n"; } } } } //運行結果 user@NLP ~/vsworksapce $ g++ openMP12.cpp -fopenmp user@NLP ~/vsworksapce $ ./a.out parallel section1 sectio2 after sectio2 sectio3 after sectio3 parallel parallel parallel parallel parallel parallel parallel parallel parallel parallel parallel
4、還有一些omp_get_wtime、for、while循環中的並行處理、OpenMP critical section、OpenMP實現鎖和互斥、以及firstprivate
和lastprivate
指令等一些 openMP的使用可以參考(https://www.ibm.com/developerworks/cn/aix/library/au-aix-openmp-framework/)
(三)、openMP簡單測試
1、簡單的測試--不限制線程數量
-
#include <omp.h> #include <time.h> #include <iostream> #include <ctime> int main() { time_t start,end1; time( &start ); int a = 0; #pragma omp parallel for for (int i = 0; i < 100; ++i) { for (int j = 0; j < 1000000000; j++); //std::cout<< a++ << std::endl; } time( &end1 ); double omp_end = omp_get_wtime( ); std::cout<<std::endl; std::cout<<"Time_used " <<((end1 - start))<<"s"<<std::endl; std::cout<<"omp_time: "<<((omp_end - omp_start))<<std::endl; return 0; }
- 從下面的圖表可以看出使用openMP的運行時間明顯少於不使用openMP。
2、簡單的測試--限制線程數量
-
#include <omp.h> #include <time.h> #include <iostream> #include <ctime> int main() { time_t start,end1; time( &start ); int a = 0; double omp_start = omp_get_wtime( ); #pragma omp parallel for num_threads(8) for (int i = 0; i < 100; ++i) { for (int j = 0; j < 1000000000; j++); } time( &end1 ); double omp_end = omp_get_wtime( ); std::cout<<std::endl; std::cout<<"Time_used " <<((end1 - start))<<"s"<<std::endl; std::cout<<"omp_time: "<<((omp_end - omp_start))<<std::endl; return 0; }
- 從下面的圖表能夠看出,線程數量對程序運行時間也是有一定的影響的,影響的大小和程序運算數據量有關。
3、簡單測試--提升數據量,限制線程數量
-
#include <omp.h> #include <time.h> #include <iostream> #include <ctime> int main() { time_t start,end1; time( &start ); int a = 0; double omp_start = omp_get_wtime( ); #pragma omp parallel for num_threads(12) for (int i = 0; i < 1000; ++i) { for (int j = 0; j < 1000000000; j++); } time( &end1 ); double omp_end = omp_get_wtime( ); std::cout<<std::endl; std::cout<<"Time_used " <<((end1 - start))<<"s"<<std::endl; std::cout<<"omp_time: "<<((omp_end - omp_start))<<std::endl; return 0; }
- 線程數量對程序的運行時間是有影響的,如果繼續提升數據運算量,openMP的實驗效果會更加明顯。
4、簡單測試--降低數據量,限制線程數量
-
#include <omp.h> #include <time.h> #include <iostream> #include <ctime> int main() { time_t start,end1; time( &start ); int a = 0; double omp_start = omp_get_wtime( ); #pragma omp parallel for for (int i = 0; i < 1000; ++i) { for (int j = 0; j < 10000; j++); } time( &end1 ); double omp_end = omp_get_wtime( ); std::cout<<std::endl; std::cout<<"Time_used " <<((end1 - start))<<"s"<<std::endl; std::cout<<"omp_time: "<<((omp_end - omp_start))<<std::endl; return 0; }
- 當數據量很小的時候,使用或者不使用openMP對於程序的運行時間影響不大。
(四)、openMP學習參考
- 通過 GCC 學習 OpenMP 框架:https://www.ibm.com/developerworks/cn/aix/library/au-aix-openmp-framework/
-
Guide into OpenMP : http://bisqwit.iki.fi/story/howto/openmp/