從06年開始,多核開發已經越來越多的成為所有應用設計必須考慮的問題。我使用MingGW+CodeBlocks來測試OpenMP多核計算架構。雖然VC8裡面已經有了對OpenMP的支援,但是VC體積有點大,而且眾所周知的MS編譯器在相容性上的問題,所以決定採用標準的GCC來做開發。
OpenMP只是並行開發的一種庫,支援多核開發本質是將原本單線程的程式或演算法變成多線程執行。OpenMP採用了類似Java的Annotation的方法來支援自動將任務轉換成多線程,例如如果你的機器是雙核的,自動將一個10000次的for迴圈自動分成兩個5000次的迴圈,如果你的機器是四核的,則自動分成4個2500次的迴圈。
1 安裝MingGW
GCC目前最穩定的版本是3.4.5,此外4.3.0裡面預設對OpenMP進行支援。因此最好在機器上同時裝兩個版本。
Windows下使用GCC可以使用MingGW和Cygwin,我個人認為Cygwin過於龐大了,所以選用MingGW。
在https://sourceforge.net/project/showfiles.php?group_id=2435中下載MingGW
對於GCC3一般下載以下幾個包:下載到C:/MinGW3目錄中,然後直接解壓到目前的目錄下。
mingw-runtime-3.9.tar.gz
gcc-core-3.4.5-20060117-3.tar.gz
gcc-g++-3.4.5-20060117-3.tar.gz
gdb-6.8-mingw-3.tar.bz2
w32api-3.12-mingw32-dev.tar.gz
binutils-2.19-mingw32-rc1-bin.tar.gz
gdb-6.8-mingw-3.tar.bz2
但是由於要開發OpenMP,所以還要再使用GCC4,一般包括以下幾個包,從加粗的部分可以看到,最大的區別是gcc核心庫的版本。下載到C:/MinGW4目錄中,然後直接解壓到目前的目錄下。
mingw-runtime-3.9.tar.gz
gcc-4.3.0-20080502-mingw32-alpha-bin.tar.gz
gdb-6.8-mingw-3.tar.bz2
w32api-3.12-mingw32-dev.tar.gz
binutils-2.19-mingw32-rc1-bin.tar.gz
gdb-6.8-mingw-3.tar.bz2
MingGW安裝好之後,將C:/MingGW/bin 加入到PATH變數裡面就可以在命令列下面是用GCC了。
2 CodeBlocks
這是MingGW官方Wiki裡面推薦的開源IDE,我試用了一下,基本編譯調試都沒有什麼問題。
請到以下地址下載http://www.codeblocks.org/downloads/5
安裝好之後,在菜單Settings -> Compiler and debugging settings裡面的Toolchain executables裡面,可以切換不同的GCC版本。
3 使用OpenMP
如果想讓編譯器能夠編譯OpenMP,首先在上面的配置中,使用C:/MinGW4.
然後再Compiler settings裡面的Other Options裡面填入-fopenmp
在Linker settings裡面的Other linker Options裡面填入-lgomp -lpthread
如果在命令列下編譯,可以使用命令
g++ -fopenmp main.cpp -lgomp -lpthread -o main.exe
注意如果發生一些找不到引用的錯誤,多辦的可能就是沒有加上-lgomp -lpthread
好,到此位置,我們就可以開發OpenMP應用了,下面給出幾個例子,都是網上的,不過我稍微改了一下:
- #include <stdio.h>
- #include <omp.h>
- #include <time.h>
- using namespace std;
- void eg_print()
- {
- #pragma omp parallel
- printf ("[%d] Hello/n", omp_get_thread_num());
- }
- void eg_for()
- {
- #pragma omp parallel for
- for(int i = 0; i <10; i++)
- {
- printf("i = %d/n", i);
- }
- }
- void eg_long_for()
- {
- int c = 0;
- clock_t t1 = clock();
- for(int i = 0; i <1000000000; i++)
- {
- c++;
- }
- clock_t t2 = clock();
- printf("Count = %d, t2 = %d, t1 = %d, Time = %d/n", c, t2, t1, t2-t1);
- }
- int main()
- {
- //eg_print();
- //eg_for();
- //測試
- clock_t t1 = clock();
- #pragma omp parallel for
- for( int j = 0; j <2; j++ )
- {
- eg_long_for();
- }
- clock_t t2 = clock();
- printf("Total time = %d/n", t2-t1);
- eg_long_for();
- return 0;
- }