紀錄|多寫單讀併發流與cameron、tbb併發隊列性能對比

我的作品ConcurrencyWriteStream,提供多線程寫單線程讀+多線程探測有無數據的功能,其元素不定長,可用於直接存儲多類型lambda作爲異步任務調度核心。
cameron似乎是目前網絡上最優化的併發隊列,提供了多(線程)寫多讀併發功能,其元素爲泛型T。
tbb的concurrent_queue與其類似。
boost的併發隊列各方面性能都不如tbb,因此性能數據不列出。

(以下單位均爲M/s 百萬次每秒)
注:new/malloc的性能大致爲單線程25M/s數量級。
std::queue的性能大致爲入隊70M,出隊670M。
基於鎖的1線程寫1線程讀隊列提供5M的出入能力,3寫1讀1.6M。

CPU@E3 1230v2 3.3GHz. DDR3 1600 16G.

M單位是百萬次每秒 cameron併發隊列 tbb併發隊列 CWS多寫單讀流 CWS流(單線程版) ringbuf(c語言)
github星多的,
其他c++不支持多線程寫入
1線程入隊① 88M
令牌60M
33.4M 32M
令牌59M
104M(達到1億次)
2線程入隊 84.7M 11.1M 31.6M
令牌42.5M
不支持
4線程入隊 80.9M 7.3M 32M
令牌40.3M
不支持
預插入後,
測1線程出隊
34M 47.62M 120M 130M(達到1.3億次)
預插入後,
測2線程出隊
7.0M
令牌6M
11.1M 不支持 不支持
預插入後,
測4線程出隊
3.8M
令牌4.3M
5.1M 不支持 不支持
1線程入隊
1線程出隊
15M
令牌22.79M
15.8M 36.5M
令牌51M
單寫77M
單寫83M@9900kf ddr4
輪流入出,各127M
(自產自銷)
85M
必須註冊工作線程,
空間尺寸固定
2線程入隊
1線程出隊
34.6M
令牌49M
不支持 22M
3線程入隊
1線程出隊
22.5M
令牌30.5M
19.43M 33.4M
令牌47M
不支持 12M
7線程入隊
1線程出隊
(只有4線程+4超線程)
22.62M
令牌30.55M
22.21M 29M
令牌40M
不支持 7.7M

注①:僅入隊性能高是沒有用的,最終還是要看出隊性能。
注②:CPU核心數與線程數足夠時,每個獨立CWS流可以分別提供20~30M op/s的IO,總IO能力可以隨CWS流的數量近乎線性地增長。
注③:所謂令牌指的是提高連續插入時性能的由調用者持有的輔助變量,與批量插入不同

CWS在上述對比中,可能不太突出,但是注意CWS具備不定長元素支持能力,而其他併發隊列通常需要用new配合,僅就new int 和malloc(4) 而言就需要單線程每秒能支撐25M次申請(不含釋放),與併發隊列組合後,顯然組合後性能用數學算法簡單可得1(1/80M+1/25M)=19M,並且由於其糟糕的內存分佈性質,內存不友好,性能必然繼續下降。奇虎360的Github項目EVPP中使用的基於cameron的多生產者單消費者的異步任務隊列,在其評測中提供了4M/s的調度能力(https://github.com/Qihoo360/evpp/blob/master/docs/benchmark_lockfree_vs_mutex_cn.md),而基於CWS的異步調度隊列,仍然提供25M+/s的超高性能。

另外cameron具備批量插入能力,性能可達200M/s ~ 300M/s。然而CWS理論上可以插入一個大對象,然後在以單線程方式將其分割成大量小對象,這個過程是完全並行獨立的。(CWS對申請4字節元素或100字節元素,性能上幾乎不敏感,影響速度很小)。可以預期插入性能同樣能達到10倍~20倍。但是在實際應用過程中,批量插入幾乎是用不到的。

CWS多線程投遞lambda,
單線程逐個執行並銷燬lambda(次)
ringbuf投遞字符數據(次)
1線程 27M 64M
2線程 22M 22M

最後CWS內部數據還有在並行環境下,直接整體壓縮、批量存儲到文件、發送到網絡的特別功能,這是其他併發隊列所無法做到的。


3.3GHz cpu 實現 77Mop/s意味着45個cpu週期,13ns完成一個數據的投遞。


CPU對比

E3 1230v2 3.3GHz 4核心8線程 ddr3 77M op/s
I9 9900kf 3.6GHz 8核16線程 ddr4 83M op/s
騰訊雲E5-26xx v4 1核心1線程 2.39GHz 36M op/s

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章