看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) LINUX G++ 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) pthread 問題(Question): 小弟之前有發一篇一樣的問題 有用板友給的意見 用系統的同步函數寫了一支平行程式 不過因為呼叫的太頻繁 反而跑起來變慢了 所以目前自己試寫了一個同步的函數 不過似乎有點問題 想請各位給我一點意見 問題是這樣的 我想要生出k條thread id 0~k-1 讓它們在固定的地方等全部人都到齊 再往下做 所以我就想用一個thread數量大小的array叫round_flag 然後每個人各自有lock_off變數來計步 當我做到這個固定點 我就把round_flag中此thread的id對應的那格寫入lock_off 然後去確認其他人的round_flag是否也是lock_off或lock_off+1 (lock_off+1是因為會有人率先通過馬上把lock_off+1又存進來 所以若有這種情況也要給他通過) 不過我跑的時候只有一條thread會通過 之後就卡住了 我記得同樣作法在windows下是可以順利跑完 請各位給我一點意見 謝謝 預期的正確結果(Expected Output): 應該要可以順利跑完 錯誤結果(Wrong Output): 跑到一半卡住 程式碼(Code):(請善用置底文網頁, 記得排版) http://pastebin.com/cf3NVrU1 -- ※ 發信站: 批踢踢實業坊(ptt.cc)
akasan:用 pthread_barrier 阿... 01/24 19:16
XXaa:恩 我就是用那個做的 不過call太頻繁 反而比沒生thread慢囧 01/24 19:19
akasan:來點詳細的演算法內容吧 01/24 19:42
我那支程式主要是 生k條thread t0~tk-1 由t0負責準備資料 其他人等資料準備完 所有人一起開始做 之後其他人繼續等 t0準備資料 如此直到做完 所以會分兩塊 if(ID==t0){ while(還有剩餘資料){ 準備資料; pthread_barrier_wait //等大家到齊 一起做; <-主要就差這裡 原本只有一個人在做 現在生k個一起做 理論上可縮短時間 至少不會比1人作慢吧? pthread_barrier_wait //等大家都做完 } } else{ //ID!=t0 while(還有剩餘資料){ pthread_barrier_wait //等大家到齊 if(有工作做) 一起做; pthread_barrier_wait //等大家都做完 } } 不過跑出來的結果 比只有1人做慢很多 推測是pthread_barrier_wait叫的太頻繁所以變慢 所以我這篇才會想自己寫一個同步函數看看
lausai:如果是CPU-bound 多執行緒是有可能會變慢 如果是IO-bound再 01/24 20:27
lausai:考慮用多直行緒吧~ 01/24 20:28
XXaa:不過我覺得很奇怪 為啥我自己寫的函數會卡住 應該會跑完才對 01/24 20:40
XXaa:可以請大大幫我看一下code嗎? 01/24 20:41
※ 編輯: XXaa 來自: 114.42.155.97 (01/24 21:13)
lausai:你的sample code我跑是沒問題的可以跑完 01/24 21:30
XXaa:奇怪 那為啥我跑會卡住>"< 01/24 21:47
IrisXIII:把round_flag 改宣告成 volatile 試試 01/24 23:35
XXaa:用樓上大大的改法就可以了~~~感謝 原來是volatile QQ 01/25 09:18
akasan:資料每次都有相依性?(這次運算用到上次結果? 01/25 09:46
akasan:還有最慢的是同步行為本身而不是pthread_barrier實作慢 01/25 09:47
XXaa:資料有相依性 看起來是同步的太頻繁 這種分法失敗了嗎ˊ ˋ 01/25 09:50
XXaa:剛剛測的結果 自己寫的while同步比pthread_barrier快一點 01/25 09:51
XXaa:不過整體還是比沒生thread跑慢很多就是了 60s->240s 慢4倍囧 01/25 09:52
linotwo:慢的原因可能有 busy waiting, context switch, cache同步 01/25 10:06
linotwo:也許把執行緒之間的工作切割乾淨再來跑會比較好。 01/25 10:08
linotwo:也可以試試看把準備好的資料丟到佇列裡,減少等待的時間 01/25 10:12