[問題] 問書- about openmp

看板C_and_CPP (C/C++)作者 (藍影)時間14年前 (2011/08/14 14:56), 編輯推噓1(1014)
留言15則, 5人參與, 最新討論串1/2 (看更多)
各位先進好, 小弟最近有興趣想摸摸 Open mp , 有些程式演算法改完後, 想讓效能更好, 但往往會卡住一些莫名的地方, 如 fibonacci number (for array) (應說是對 open mp 很不熟關係), 可能遇到有些情況不適用卻不自知, 也可能是有一些技巧可解決也不自知, 甚至有些狀況讓我很意外, 如 ----- /* code 1 - bad opmmp */ #pragma omp parallel for /* sorry, 是放外面效率較差 */ for (int iterator=0; iterator<ITER; ++iterator) for (int i=0;i<SIZE;++i) in[i] = i + 2680; /* code 2 - normal */ for (int iterator=0; iterator<ITER; ++iterator) for (int i=0;i<SIZE;++i) in[i] = i + 2680; 出來的結果竟是 code2 比 code1 還快一些, 莫名的吃驚.. ----- 想請教是否有書籍專門在介紹 open mp 概念及使用 ? (可能會扯到一些 thread, 無妨) 另一個問題是,目前 search 一些資源 (msdn 除外), 似乎都會再特別提到 intel 主板,這部份不知是否有一定關係? 不是 intel 主板的話會有差嗎? 謝謝各位不吝回覆與指教, 感激不盡! -- When I saw the turth of love, I feel the pain which the world brings to me. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.78.41

08/14 14:58, , 1F
題外話,t大的守備範圍真的很廣
08/14 14:58, 1F

08/14 15:07, , 2F
哪裡,都是版友們不吝指導牽成而已。
08/14 15:07, 2F

08/14 15:28, , 3F
我覺得這兩個有兩個地方不一樣...
08/14 15:28, 3F

08/14 15:29, , 4F
不... 是3個 = =
08/14 15:29, 4F

08/14 15:31, , 5F
iterator!=ITER iterator<=ITER ....
08/14 15:31, 5F

08/14 15:31, , 6F
i!=SIZE i<SIZE ...
08/14 15:31, 6F
謝謝指正, 確實沒改好,code2 確實仍比 code1 快一點.

08/14 15:51, , 7F
要不要看一下code2的asm code? 感覺code2可能可以被
08/14 15:51, 7F

08/14 15:53, , 8F
compiler optimize掉....@_@"
08/14 15:53, 8F

08/14 15:56, , 9F
同樓上 現在優化的能力都有點可怕了...@@
08/14 15:56, 9F
抱歉上面程式碼錯不少 (openmp compare operator 也不能用 != , <=) 我把我整段測過東西及結果放上來參考好了 <header 略> #define ITER 100000 #define SIZE 20000 #define ELASPE(msg, t) {printf("%s elaspe: %ld\n",(msg),clock() - (t));} int main(void) { int i, j, in[SIZE]={0}; clock_t t; /* code 1 - omp inside, takes 891 */ memset(in, 0, SIZE); t=clock(); for (i=0;i<SIZE;++i) #pragma omp parallel for for (j=0; j<ITER; ++j) in[i] = i + 2680; ELASPE("code1 (openmp inside)", t); /* code 2 - normal, takes 1406 */ memset(in, 0, SIZE); t=clock(); for (i=0;i<SIZE;++i) for (j=0; j<ITER; ++j) in[i] = i + 2680; ELASPE("code2 (normal)", t); /* code 3 - omp outside, takes 12062 */ memset(in, 0, SIZE); t=clock(); #pragma omp parallel for for (i=0;i<SIZE;++i) for (j=0; j<ITER; ++j) in[i] = i + 2680; ELASPE("code3 (openmp outside)", t); return 0; } 這裡的真正問題是在於,parallel for 放的位置不對,效率會變差, 但的確就是不知道該如何判斷要放哪裡,和什麼參數有關, 從產生之 asm 看不出個所以然,故才在想應是哪些 background 不懂, 所以才想問有沒有書會特別拉 openmp / thread 在討論 XD 以上程式碼,vs 2008編譯參數 /O2 /Oi /Ot /GT /GL /D "_MBCS" /FD /EHsc /MT /GS- /arch:SSE2 /GR- /openmp /FAs /Fa"Release\\" /Fo"Release\\" /Fd"Release\vc90.pdb" /W4 /nologo /c /wd4996 /errorReport:prompt 出來的 asm : https://gist.github.com/1144706 ※ 編輯: tropical72 來自: 180.177.78.41 (08/14 16:40)

08/14 18:05, , 10F
看起來是有cache locality的問題
08/14 18:05, 10F

08/14 18:06, , 11F
omp for放在j的時候threads寫到一段連續的區塊
08/14 18:06, 11F

08/14 18:07, , 12F
omp for放在i的時候thread寫的位置錯開
08/14 18:07, 12F

08/14 18:08, , 13F
如果離得夠遠不在同一條cache line上就會影響效能
08/14 18:08, 13F

08/14 18:08, , 14F
asm code應該不容易看出來 尤其你又開O2
08/14 18:08, 14F

08/14 23:07, , 15F
謝謝 p 大指教*^_^*
08/14 23:07, 15F
文章代碼(AID): #1EHt6XDb (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1EHt6XDb (C_and_CPP)