[問題] 使用multi-thread去接收封包反而慢??

看板C_and_CPP (C/C++)作者 (湯姆熊)時間10年前 (2015/06/04 09:12), 10年前編輯推噓4(4039)
留言43則, 9人參與, 最新討論串1/2 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Visual studio 2013 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) 問題(Question): 寫了Socket的程式,Server端傳檔案,然後Client端接收並寫入檔案 Multi-thread開N個threads同時去分別接收UDP封包, 換句話說,想要將封包拆成N份並同時接收 所以預期是希望所需總接收時間會下降 但我發現單一thread接收的時間反而比較快... 不清楚這可能的問題是甚麼 會是因為context switching過多?? 如果是的話我有辦法從自己的code看出來嗎?? 補充說明(Supplement): API是使用OpenMP 舉個目前測試出的結果,讓大家看看能不能更清楚我可能忽略或做錯的狀況 thread個數為1時 接收10MB的檔案約須時2.5秒 thread個數為2時 若分別接收9MB和1MB,共須時3秒 若分別接收5MB和5MB,共須時5秒 -- ╔《新版十二生肖》═════════════════════════════╗ ║ ◣◣ ˍ ║ ●●╰‧‧ [ ] ιι . . - - ˍ▁ '' .. '〒' '. ' ' ' ξ . . '@@ ' ˊˋ ★︰ / ██╯ / @@@@ █◤ ˋˊ ║ ╚═══" " ════════════ ""══"═"════════liszt1025╝ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 112.104.118.100 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1433380362.A.1EB.html ※ 編輯: r596twy (112.104.118.100), 06/04/2015 09:17:01

06/04 09:21, , 1F
傳"檔案"用UDP你可能得先了解UDP,另外你應該是共用同個
06/04 09:21, 1F

06/04 09:22, , 2F
server socket吧? 我想他應該同時間只能有一人去讀取!
06/04 09:22, 2F
UDP,不確定有無誤解,我目前對它的了解有: 1.無掉封包重傳機制 (TCP才有) 2.與TCP不同的是,將大多欄位拿來給檔案內容(payload), 所以同時可傳送更多的檔案內容 3.UDP不管接收順序和有無掉封包,所以不用等Client端傳確認訊息,會一直傳 server socket我是只有用一個, 因為我原本是希望TCP可以做到N個threads同時傳送和接收封包 但TCP似乎要在socket中開N個ports(不確定是否認知錯誤) 而UDP不像TCP會有很多耽擱時間(許多機制導致) 且以為UDP是Server傳完一個封包就一直傳,不管Client是否已收完(此段不確定) 所以才打算在UDP上試試看,而結果似乎不對 目前我可能的猜測是: 1.Context switching,但正常不是一個核心一個thread嗎?還會有這問題? 2.Single connection,同一時間只有傳一個封包,但如果是如此,怎還有時間反而上升的情形? 現在有開多個threads同時接收封包的實際應用嗎? 如果有的話,想請問他們是怎作的? ※ 編輯: r596twy (112.104.118.100), 06/04/2015 09:52:43

06/04 10:01, , 3F
ios 只有一個network thread. just like media thread
06/04 10:01, 3F
不太確定你的意思,不知道有沒誤解 是說作業系統可能有差?還是說網路傳輸封包對於ios只能一筆收完才能傳下一筆? 我是Win7 64-bit 測過簡單的i = i + 1運算兩百萬次 是發現時間的確有下降 也檢查thread編號的確有各別在執行 但不確定這樣的結果是否也在傳輸方面適用 ※ 編輯: r596twy (112.104.118.100), 06/04/2015 10:08:21

06/04 10:02, , 4F
sorry 我以爲我在mac dev版
06/04 10:02, 4F

06/04 10:36, , 5F
會不會寫檔變慢的....XD
06/04 10:36, 5F
我的寫法是接收一次寫一次,如果改成全部接收後再寫入應該會變快 但一個thread和多個threads感覺總寫入次數應該會很接近才是 所以我如果這樣改,可能是全部時間都有縮短, 但多個thtreads時間比一個thread還耗時好像還是沒辦法解決?

06/04 10:39, , 6F
要不要多插幾條網路線看看
06/04 10:39, 6F

06/04 10:40, , 7F
IO類的東西硬體側thread超少很正常
06/04 10:40, 7F

06/04 10:41, , 8F
你派10億人過去還不是都卡同一個窗口
06/04 10:41, 8F

06/04 10:41, , 9F
海關還會大塞車
06/04 10:41, 9F

06/04 10:42, , 10F
IO通常少量大包資料效率會比較好
06/04 10:42, 10F
多插幾條網路線跟在socket多開幾個ports和connect去連接是一樣效果嗎? 還是說這兩者是要並行一起作的? ※ 編輯: r596twy (112.104.118.100), 06/04/2015 10:57:59

06/04 11:38, , 11F
用IOCP?
06/04 11:38, 11F
不好意思,不太確定你說得是啥, 可以說清楚點嗎? 感謝你

06/04 11:49, , 12F
處理同一件事用multithread會變慢是正常的, 邏輯沒
06/04 11:49, 12F

06/04 11:50, , 13F
相依性才有加速效果
06/04 11:50, 13F

06/04 11:52, , 14F
題外話UDP在現實網路環境其實很不穩, 用它傳檔感覺不
06/04 11:52, 14F

06/04 11:52, , 15F
太適合
06/04 11:52, 15F
有點不確定你說的邏輯相依性是甚麼 是指thread與thread之間所作的事情關連性叫邏輯相依性? 如果是的話,應該是要彼此無關,不會要等彼此的結果出來所拖累 multi-thread才會加快不是嗎? 然後我會想用UDP的原因在於 因為我最終是要傳遞影像經過壓縮後的bin檔 類似要作影像串流的網路傳輸 而我之前查過文獻得知 目前大多影像串流和線上視訊等等 大多為了速度而犧牲可靠度選擇UDP 當然也有如Youtube 是用TCP來搭配應用 ※ 編輯: r596twy (112.104.118.100), 06/04/2015 13:11:47

06/04 13:26, , 16F
他們都是同一條線,沒有那種開n thread網路速度就n倍
06/04 13:26, 16F

06/04 13:26, , 17F
的,可以的話中華電信就不用賺了
06/04 13:26, 17F
我想減少的是接收時間,不是傳輸時間

06/04 15:47, , 18F
那是streaming播放才用UDP 你不能保證封包正確性檔案收
06/04 15:47, 18F

06/04 15:48, , 19F
下來checksum都不對 播放直接吃format error
06/04 15:48, 19F

06/04 15:49, , 20F
streaming影格壞了跳過就好 你影片檔這樣搞會爛掉
06/04 15:49, 20F
我知道UDP的缺點,我上面回覆有說啦,我這實驗主要是為了影像串流(streaming)而作的 所以影格丟失就丟失,無所謂 而checksum這邊的敘述怎有點怪怪的 checksum不是驗證收到封包是否正確的一種方法嗎? 既然已到播放那一環了,那表示接收封包被視為正確的 才會把內容送去decoder解碼並播放 這checksum跟format error沒半點關係阿 然後會造成不能播放的原因通常有兩點, 1.Intra frame丟失,造成部分需要參考此畫面資訊重建的畫面不能解碼並播放 必須到下一個group of picture(GOP)才可以繼續 2.描述影像相關參數丟失(如長寬比、畫面顯現時間等),而造成整段影片不能解碼 但現在影像編碼都有良好的糾錯以及專為此情況處理的傳送機制, 所以這情況基本上很難發生

06/04 17:29, , 21F
想想窗口(Port)只有一個,不會因為你有多少人(Thread)而
06/04 17:29, 21F

06/04 17:30, , 22F
變快。
06/04 17:30, 22F

06/04 17:45, , 23F
要變快應該去調教接收buffer與系統網路buffe的大小
06/04 17:45, 23F

06/04 17:46, , 24F
如linux中net.core.rmem_max
06/04 17:46, 24F

06/04 17:52, , 25F
想串流的話應該走RTP/RTSP/RTCP之類的protocal
06/04 17:52, 25F

06/04 17:53, , 26F
可以去看看live555、VLC之類的open source
06/04 17:53, 26F

06/04 18:04, , 27F
另外多網卡 + network bonding應該也能有效提升速率
06/04 18:04, 27F
live555和VLC我也正在研究它們是如何運作的 另外RTP/RTCP和RTSP是應用層方面的 跟傳輸層方面的TCP/UDP是分開考慮 彼此間只是相互協作關係 而目前我是想觀察一些現象,所以先從傳輸層方面開始觀察 傳輸層方面的實驗有一定了解後,才進一步將應用層拿進來考慮 多網卡感覺應該可以提速, 那如果我同時開多個port,也能達到提速效果嗎?

06/04 22:28, , 28F
阿就漏斗啊 裝水量再大 出水量還是不變
06/04 22:28, 28F
有考慮到這可能是造成問題的原因,Single connection 但是如果真是這問題, 既然總水量一樣,換句話說就是總封包個數一樣 且出水速度一樣,換句話說就是封包接收時間一樣 那單一thread和多個threads彼此花費的時間應該要相近 但現在看到的卻不是這樣的結果... ※ 編輯: r596twy (112.104.118.100), 06/05/2015 08:31:57 ※ 編輯: r596twy (112.104.118.100), 06/05/2015 08:32:47 ※ 編輯: r596twy (112.104.118.100), 06/05/2015 08:36:05 ※ 編輯: r596twy (112.104.118.100), 06/05/2015 08:36:36 ※ 編輯: r596twy (112.104.118.100), 06/05/2015 08:49:53

06/05 08:41, , 29F
"overhead"
06/05 08:41, 29F

06/05 09:25, , 30F
不可能相近因為socket send/recv 都是 Thread safety
06/05 09:25, 30F

06/05 09:26, , 31F
本身就是atomic operation所以,同時間只會有1個thread
06/05 09:26, 31F

06/05 09:28, , 32F
在讀或寫,後面的Thread都在排隊,多了排隊跟切換的時間
06/05 09:28, 32F

06/05 09:30, , 33F
所以你每次能read buffer的大小,會有直接的影響,因為每
06/05 09:30, 33F

06/05 09:30, , 34F
讀完一次,還沒讀完馬上就要再換人。
06/05 09:30, 34F

06/05 09:31, , 35F
多connection應該能有一點改善才對,但仍局限於網卡頻寬
06/05 09:31, 35F

06/05 09:32, , 36F
另外live555那些TCP, UDP都有支援!
06/05 09:32, 36F

06/06 20:02, , 37F
你的情況接收時間最快上限就是傳輸時間 是被網卡跟線
06/06 20:02, 37F

06/06 20:03, , 38F
路侷限住的 多thread不會變快 而會變慢的原因樓上說的
06/06 20:03, 38F

06/07 10:24, , 39F
thread是增加吞吐量, 你要比應該是比檔案開thread下載
06/07 10:24, 39F

06/07 10:25, , 40F
的時間vs檔案ㄧ前一後下載的時間和
06/07 10:25, 40F

06/07 10:27, , 41F
假設下載1MB的人不幸比下載9MB的另一個人晚一點開始
06/07 10:27, 41F

06/07 10:29, , 42F
多thread會讓兩人無感; 單thread會讓1MB的人很有感
06/07 10:29, 42F

06/07 10:30, , 43F
因為他要先等9MB傳完
06/07 10:30, 43F
文章代碼(AID): #1LRwOA7h (C_and_CPP)
文章代碼(AID): #1LRwOA7h (C_and_CPP)