contributed by <mingnus
>
ncku
sysprog
mergesort
很敏銳的觀察,很好!請一併參照 GLib 的 Asynchronous Queues,裡頭的命名和 programming model 很值得學習 jserv
簡單比較list實作, 感覺kernel這種允許自訂資料結構的做法比較有彈性 mingnus
non-circular list也不利於加入節點到list結尾, 例如merge_list()就必須維護一個指向
_list
結尾的指標current
。不過話說回來merge_list()或許不用另外宣告_list
, 只要把list b併到list a就好 mingnus
kernel list_sort.c的做法滿特別, 它是把原本的list打散成數個null-terminated sorted sublist, 再把它們合併 mingnus
改用一般寫法也比較好理解
cut_func()是用cut_count決定是否要切割傳入的sublist, 在多執行緒環境下可能導致sublists長度不均
merge()以FIFO方式合併sublists, 先排完的sublist先合併 (排序完成的sublist儲存於全域變數tmp_list, 等待另一個sublist排序完成後合併), 這樣在多執行緒時無法預測哪些sublist會互相合併, 長度不同的sublist也可能互相合併。為何不在merge()的參數指定要合併的sublists?
還沒想到確實做法, sibling list的資訊可能要儲存在list head mingnus
你需要重新回顧資料結構和演算法的設計,可參考 Skip list jserv
cut_func()在分割list時重覆呼叫list_nth(), 實際上可用list->head->next取代
cut_func()
或merge()
)為了檢查全域變數, 必須持有全域mutex data_context::mutex
, 這樣容易造成lock contention。但這兩種task可以不必共用mutex:
cut_thread_count
非常好!透過
mutrace
,你可以發現,事實上有些 lock 是根本不需要存在,就像之前 thread pool 的設計中,善用 ring buffer 就可以省去部分 lock 的成本 jserv
threadpool worker thread function task_run()
以polling方式詢問taskqueue, 極易造成lock contention。傳統做法是採用conditional variable避免polling。
task function命名不佳, 不易看出程式脈絡
gprof分析
TODO
Some articles about merge sort
Some articles about parallel merge sort
參考共筆