worksteal的場景
對於一個線程池,每個線程有一個隊列,想象這種場景,有的線程隊列中有大量的比較耗時的任務堆積,而有的線程隊列卻是空的,現象就是有的線程處於飢餓狀態,而有的線程處於消化不良的狀態,這時就需要一種方法來解決這個問題。
需要worksteal,顧名思義就是任務竊取,當一個線程處於飢餓狀態時,它就會去其它的線程隊列中竊取任務,解決線程飢餓導致的效率底的問題。
worksteal要點
- 每個工作線程將任務放到它內部的隊列中;
- 隊列是一個雙端隊列,支持LIFO的push_front和pop_front操作和FIFO的take操作。
- 工作線程處理任務通過LIFO來處理最新的任務。
- 當一個線程處理完了隊列中的任務之后,它會試圖竊取其他線程隊列的任務,根據FIFO從隊列的尾部取任務。
- 如果竊取任務失敗則繼續嘗試,直到所有的線程隊列都沒有任務了。
worksteal值得探討的問題
worksteal的適用場景
worksteal適用場景是任務之間的耗時相差比較大,即有的任務很耗時,有的任務很快完成,這種用worksteal很合適;如果任務的耗時很平均則不適合,因為竊取任務也是需要搶占鎖的,會造成額外的消耗。
竊取任務的策略
有很多種任務竊取策略,比如從任務最多的線程中竊取或隨機竊取,需要根據實際情況來選擇。
竊取任務的粒度
是每次竊取一個任務還是竊取一批任務也是需要考量的,如果竊取的一批任務比較耗時,又會導致其它線程來竊取,這樣造成了無謂的消耗;如果一次竊取一個任務,而任務很快完成,這又導致重新竊取,降低了效率。這個粒度也是需要根據實際情況調整的。
參考資料
Scheduling Multithreaded Computations by Work Stealing