來源自 這裡
Preface:
對於一般單一執行緒(single thread)的程式,多核心的處理器並沒有辦法提升它的處理效能;不過對於多執行緒(multi thread)的程式,就可以透過不同的核心同時計算,來達到加速的目的了!簡單的例子,以單執行緒的程式來說,一件事做一次要十秒的話,要做十次,都丟給同一顆核心做的話,自然就是 10 秒 * 10 次,也就是 100 秒了;但是以多執行緒的程式來說,它可以把這一件事,分給兩顆核心各自做,每顆核心各做 5 次,所以所需要的時間就會接近 50 秒!
當然,多執行緒的程式實際上沒這麼簡單。在工作的切割、結合上,也是要多花時間的,所以在現實中,即使最佳狀況,雙核心的效能也不會是 1 + 1 = 2 這樣的理想化。除此之外,也不是所有工作都是可以切割的!很多工作是有關聯性的,這樣如果直接切割給不同的處理核心各自去平行運算,出來的結果是肯定有問題的。而且,多執行緒的程式在編寫、維護上,也都比單一執行緒的程式複雜上不少.
不過,如果電腦本身是多處理器、多核心處理器,或是處理器擁有像 Intel Hyper-Threading Technology 這類的能在同一個時間處理多個執行緒的功能的話,那把各自獨立的工作由單一執行緒改成多執行緒,在執行的效率上,大多還是會有增進的!
多執行緒的程式:
寫程式的時候該怎麼去寫多執行緒的程式呢?一般的方法,就是真的利用 thread 的控制,去實際在程式中去產生其他的 thread 來處理。像 POSIX Threads 這套 library,就是用來產生、控制執行緒的函式庫。而像 Microsoft VisualStudio 2005 中,也有提供控制 thread 的功能。這種方法,大多就是產生多個 thread,而再由主要的 thread 把工作拆開,分給各 thread 去運算,最後再由主要的 thread 回收結果、整合。
但是,實際上要去控制 thread 是滿麻煩的~在程式的編寫上,也會複雜不少;而如果我們只是想要把一些簡單的迴圈平行化處理,用 thread library 來控制,實在有點殺雞用牛刀的感覺。這時候,用Open MP 就簡單多了!OpenMP 是一種能透過高階指令,很簡單地將程式平行化、多執行緒化的 API;在最簡單的情形,甚至可以只加一行指令,就可以將迴圈內的程式平行化處理了!
OpenMP 的基本使用:
要在 Visual C++ 2005 中使用 openMP 其實不難,只要將 Project 的 Properties 中 C/C++ 裡 Language 的 OpenMP Support 開啟(參數為 /openmp),就可以讓 VC++2005 在編譯時支援 OpenMP 的語法了;而在使用到 OpenMP 的檔案,則需要先 include OpenMP 的 header file : omp.h
而要將 for 迴圈平行化處理,該怎麼做呢?非常簡單,只要在前面加上一行:
也可以實際用一段簡單的程式,來弄清楚它的運作方式:
上面的程式,在
main() 是一個很簡單的迴圈,跑十次,每次都會呼叫 Test() 這個函氏,並把是迴圈的執行次數(i)傳進 Test() 並列印出來。想當然耳,它的結果會是:
而如果想利用 OpenMP 把 mian() 裡面的迴圈平行化處理呢?只需要修改成下面的樣子:
夠簡單吧?重頭到尾,只加了兩行!而執行後,可以發現結果也變了!
可以從結果很明顯的發現,他沒有照著 0 到 9 的順序跑了!而上面的順序怎麼來的?其實很簡單,OpenMP 只是把迴圈 0 – 9 共十個步驟,拆成 0 – 4, 5 – 9 兩部份,丟給不同的執行緒去跑,所以數字才會出現這樣交錯性的輸出.
而要怎麼確定真的有跑多執行緒呢?如果本來有多處理器、多核心處理器或有 Hyper Thread 的話,一個單執行緒程式,最多只會把一顆核心的使用量吃完;像比如說在 Pentium 4 HT 上跑,單一執行緒的程式,在工作管理員中看到的 CPU 使用率最多就是 50%。而利用 OpenMP 把回圈進行平行化處理後,就可以在執行廻圈時,把兩顆核心的 CPU 都榨光了!也就是工作管理員可以看到 CPU 使用率是 100%. 或是裡可以利用 OpenMP 上面提供的函數 omp_get_num_threads() 得到目前使用幾個 threads 的數目.
Supplement:
* 簡易的程式平行化-OpenMP(二)語法說明
* 簡易的程式平行化-OpenMP(三)範例 parallel、section
* 簡易的程式平行化-OpenMP(四) 範例 for
* 簡易的程式平行化-OpenMP(五) 變數的平行化
Preface:
對於一般單一執行緒(single thread)的程式,多核心的處理器並沒有辦法提升它的處理效能;不過對於多執行緒(multi thread)的程式,就可以透過不同的核心同時計算,來達到加速的目的了!簡單的例子,以單執行緒的程式來說,一件事做一次要十秒的話,要做十次,都丟給同一顆核心做的話,自然就是 10 秒 * 10 次,也就是 100 秒了;但是以多執行緒的程式來說,它可以把這一件事,分給兩顆核心各自做,每顆核心各做 5 次,所以所需要的時間就會接近 50 秒!
當然,多執行緒的程式實際上沒這麼簡單。在工作的切割、結合上,也是要多花時間的,所以在現實中,即使最佳狀況,雙核心的效能也不會是 1 + 1 = 2 這樣的理想化。除此之外,也不是所有工作都是可以切割的!很多工作是有關聯性的,這樣如果直接切割給不同的處理核心各自去平行運算,出來的結果是肯定有問題的。而且,多執行緒的程式在編寫、維護上,也都比單一執行緒的程式複雜上不少.
不過,如果電腦本身是多處理器、多核心處理器,或是處理器擁有像 Intel Hyper-Threading Technology 這類的能在同一個時間處理多個執行緒的功能的話,那把各自獨立的工作由單一執行緒改成多執行緒,在執行的效率上,大多還是會有增進的!
多執行緒的程式:
寫程式的時候該怎麼去寫多執行緒的程式呢?一般的方法,就是真的利用 thread 的控制,去實際在程式中去產生其他的 thread 來處理。像 POSIX Threads 這套 library,就是用來產生、控制執行緒的函式庫。而像 Microsoft VisualStudio 2005 中,也有提供控制 thread 的功能。這種方法,大多就是產生多個 thread,而再由主要的 thread 把工作拆開,分給各 thread 去運算,最後再由主要的 thread 回收結果、整合。
但是,實際上要去控制 thread 是滿麻煩的~在程式的編寫上,也會複雜不少;而如果我們只是想要把一些簡單的迴圈平行化處理,用 thread library 來控制,實在有點殺雞用牛刀的感覺。這時候,用Open MP 就簡單多了!OpenMP 是一種能透過高階指令,很簡單地將程式平行化、多執行緒化的 API;在最簡單的情形,甚至可以只加一行指令,就可以將迴圈內的程式平行化處理了!
OpenMP 的基本使用:
要在 Visual C++ 2005 中使用 openMP 其實不難,只要將 Project 的 Properties 中 C/C++ 裡 Language 的 OpenMP Support 開啟(參數為 /openmp),就可以讓 VC++2005 在編譯時支援 OpenMP 的語法了;而在使用到 OpenMP 的檔案,則需要先 include OpenMP 的 header file : omp.h
而要將 for 迴圈平行化處理,該怎麼做呢?非常簡單,只要在前面加上一行:
- #pragma omp parallel for
- #include
- #include
- void Test( int n )
- {
- for( int i = 0; i < 10000; ++ i )
- {
- //do nothing, just waste time
- }
- printf( "%d, ", n );
- }
- int main(int argc, char* argv[])
- {
- for( int i = 0; i < 10; ++ i )
- Test( i );
- system( "pause" );
- }
而如果想利用 OpenMP 把 mian() 裡面的迴圈平行化處理呢?只需要修改成下面的樣子:
- #include
- #include
- #include
- void Test( int n )
- {
- for(int i=0; i<100000; i++){}
- printf( "T%d:%d, ", omp_get_thread_num(), n);
- }
- int main(int argc, char* argv[])
- {
- #pragma omp parallel for
- for(int i = 0; i<10; ++i)
- {
- Test( i );
- }
- system( "pause" );
- }
可以從結果很明顯的發現,他沒有照著 0 到 9 的順序跑了!而上面的順序怎麼來的?其實很簡單,OpenMP 只是把迴圈 0 – 9 共十個步驟,拆成 0 – 4, 5 – 9 兩部份,丟給不同的執行緒去跑,所以數字才會出現這樣交錯性的輸出.
而要怎麼確定真的有跑多執行緒呢?如果本來有多處理器、多核心處理器或有 Hyper Thread 的話,一個單執行緒程式,最多只會把一顆核心的使用量吃完;像比如說在 Pentium 4 HT 上跑,單一執行緒的程式,在工作管理員中看到的 CPU 使用率最多就是 50%。而利用 OpenMP 把回圈進行平行化處理後,就可以在執行廻圈時,把兩顆核心的 CPU 都榨光了!也就是工作管理員可以看到 CPU 使用率是 100%. 或是裡可以利用 OpenMP 上面提供的函數 omp_get_num_threads() 得到目前使用幾個 threads 的數目.
Supplement:
* 簡易的程式平行化-OpenMP(二)語法說明
* 簡易的程式平行化-OpenMP(三)範例 parallel、section
* 簡易的程式平行化-OpenMP(四) 範例 for
* 簡易的程式平行化-OpenMP(五) 變數的平行化
This message was edited 11 times. Last update was at 26/12/2013 19:34:33
沒有留言:
張貼留言