lockfree buffer test
性能測(cè)試(3): 對(duì)無(wú)鎖隊(duì)列boost::lockfree::queue和moodycamel::ConcurrentQueue做一個(gè)性能對(duì)比測(cè)試
版權(quán)聲明:本文為博主zieckey原創(chuàng)文章,轉(zhuǎn)載時(shí)請(qǐng)保留版權(quán)信息。 https://blog.csdn.net/zieckey/article/details/69803011English version : The performance benchmark of queue with std::mutex against boost::lockfree::queue and moodycamel::ConcurrentQueue
Brief
我們使用https://github.com/Qihoo360/evpp項(xiàng)目中的EventLoop::QueueInLoop(...)函數(shù)來(lái)做這個(gè)性能測(cè)試。我們通過(guò)該函數(shù)能夠?qū)⒁粋€(gè)仿函數(shù)執(zhí)行體從一個(gè)線程調(diào)度到另一個(gè)線程中執(zhí)行。這是一個(gè)典型的生產(chǎn)者和消費(fèi)者問(wèn)題。
我們用一個(gè)隊(duì)列來(lái)保存這種仿函數(shù)執(zhí)行體。多個(gè)生產(chǎn)者線程向這個(gè)隊(duì)列寫入仿函數(shù)執(zhí)行體,一個(gè)消費(fèi)者線程從隊(duì)列中取出仿函數(shù)執(zhí)行體來(lái)執(zhí)行。為了保證隊(duì)列的線程安全問(wèn)題,我們可以使用一個(gè)鎖來(lái)保護(hù)這個(gè)隊(duì)列,或者使用無(wú)鎖隊(duì)列機(jī)制來(lái)解決安全問(wèn)題。EventLoop::QueueInLoop(...)函數(shù)通過(guò)通定義實(shí)現(xiàn)了三種不同模式的跨線程交換數(shù)據(jù)的隊(duì)列。
測(cè)試對(duì)象
- 帶鎖的隊(duì)列用std::vector和std::mutex來(lái)實(shí)現(xiàn),具體的 gcc 版本為 4.8.2
- boost::lockfree::queue from boost-1.53
- moodycamel::ConcurrentQueue with commit c54341183f8674c575913a65ef7c651ecce47243
測(cè)試環(huán)境
測(cè)試方法
測(cè)試代碼請(qǐng)參考https://github.com/Qihoo360/evpp/blob/master/benchmark/post_task/post_task6.cc. 在一個(gè)消費(fèi)者線程中運(yùn)行一個(gè)EventLoop對(duì)象loop_,多個(gè)生產(chǎn)者線程不停的調(diào)用loop_->QueueInLoop(...)方法將仿函數(shù)執(zhí)行體放入到消費(fèi)者的隊(duì)列中讓其消費(fèi)(執(zhí)行)。每個(gè)生產(chǎn)者線程放入一定總數(shù)(由運(yùn)行參數(shù)指定)的仿函數(shù)執(zhí)行體之后就停下來(lái),等消費(fèi)者線程完全消費(fèi)完所有的仿函數(shù)執(zhí)行體之后,程序退出,并記錄開(kāi)始和結(jié)束時(shí)間。
為了便于大家閱讀,現(xiàn)將相關(guān)代碼的核心部分摘錄如下。
event_loop.h中定義了隊(duì)列:
std::shared_ptr<PipeEventWatcher> watcher_; #ifdef H_HAVE_BOOSTboost::lockfree::queue<Functor*>* pending_functors_; #elif defined(H_HAVE_CAMERON314_CONCURRENTQUEUE) moodycamel::ConcurrentQueue<Functor>* pending_functors_; #else std::mutex mutex_; std::vector<Functor>* pending_functors_; // @Guarded By mutex_ #endif?
event_loop.cc中定義了QueueInLoop(...)的具體實(shí)現(xiàn):
void Init() {watcher_->Watch(std::bind(&EventLoop::DoPendingFunctors, this)); }void EventLoop::QueueInLoop(const Functor& cb) { { #ifdef H_HAVE_BOOST auto f = new Functor(cb); while (!pending_functors_->push(f)) { } #elif defined(H_HAVE_CAMERON314_CONCURRENTQUEUE) while (!pending_functors_->enqueue(cb)) { } #else std::lock_guard<std::mutex> lock(mutex_); pending_functors_->emplace_back(cb); #endif } watcher_->Notify(); } void EventLoop::DoPendingFunctors() { #ifdef H_HAVE_BOOST Functor* f = nullptr; while (pending_functors_->pop(f)) { (*f)(); delete f; } #elif defined(H_HAVE_CAMERON314_CONCURRENTQUEUE) Functor f; while (pending_functors_->try_dequeue(f)) { f(); --pending_functor_count_; } #else std::vector<Functor> functors; { std::lock_guard<std::mutex> lock(mutex_); notified_.store(false); pending_functors_->swap(functors); } for (size_t i = 0; i < functors.size(); ++i) { functors[i](); } #endif }?
我們進(jìn)行了兩種測(cè)試:
測(cè)試結(jié)論
因此,上述對(duì)比測(cè)試結(jié)論,就我們的evpp項(xiàng)目中的EventLoop的實(shí)現(xiàn)方式,我們推薦使用moodycamel::ConcurrentQueue來(lái)實(shí)現(xiàn)跨線程的數(shù)據(jù)交換。
更詳細(xì)的測(cè)試數(shù)據(jù),請(qǐng)參考下面的兩個(gè)圖表。
縱軸是執(zhí)行耗時(shí),越低性能越高。
圖1,生產(chǎn)者和消費(fèi)者都只有一個(gè),橫軸是測(cè)試的批次:
圖2,生產(chǎn)者線程有多個(gè),橫軸是生產(chǎn)者線程的個(gè)數(shù),分別是2/4/6/8/12/16/20:
其他的性能測(cè)試報(bào)告
The IO Event performance benchmark against Boost.Asio : evpp is higher than asio about 20%~50% in this case
The ping-pong benchmark against Boost.Asio : evpp is higher than asio about 5%~20% in this case
The throughput benchmark against libevent2 : evpp is higher than libevent about 17%~130% in this case
The performance benchmark of queue with std::mutex against boost::lockfree::queue and moodycamel::ConcurrentQueue : moodycamel::ConcurrentQueue is the best, the average is higher than boost::lockfree::queue about 25%~100% and higher than queue with std::mutex about 100%~500%
The throughput benchmark against Boost.Asio : evpp and asio have the similar performance in this case
The throughput benchmark against Boost.Asio(中文) : evpp and asio have the similar performance in this case
The throughput benchmark against muduo(中文) : evpp and muduo have the similar performance in this case
最后
報(bào)告中的圖表是使用gochart繪制的。
非常感謝您的閱讀。如果您有任何疑問(wèn),請(qǐng)隨時(shí)在https://github.com/Qihoo360/evpp/issues跟我們討論。謝謝。
轉(zhuǎn)載于:https://www.cnblogs.com/lvdongjie/p/9681536.html
總結(jié)
以上是生活随笔為你收集整理的lockfree buffer test的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [USACO5.3]校园网Network
- 下一篇: 解决intellij IEDA mapp