日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

lockfree buffer test

發(fā)布時(shí)間:2025/4/9 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lockfree buffer test 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

性能測(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/69803011

English 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ì)象

  • evpp-v0.3.2
  • EventLoop::QueueInLoop(...)函數(shù)內(nèi)的隊(duì)列的三種實(shí)現(xiàn)方式:
    • 帶鎖的隊(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)境

  • Linux CentOS 6.2, 2.6.32-220.7.1.el6.x86_64
  • Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.60GHz
  • gcc version 4.8.2 20140120 (Red Hat 4.8.2-15) (GCC)
  • 測(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è)試:

  • 一個(gè)生產(chǎn)者線程投遞1000000個(gè)仿函數(shù)執(zhí)行體到消費(fèi)者線程中執(zhí)行,統(tǒng)計(jì)總耗時(shí)。然后同樣的方法我們反復(fù)測(cè)試10次
  • 生產(chǎn)者線程分別是2/4/6/8/12/16/20,每個(gè)線程投遞1000000個(gè)仿函數(shù)執(zhí)行體到消費(fèi)者線程中執(zhí)行,并統(tǒng)計(jì)總共耗時(shí)
  • 測(cè)試結(jié)論

  • 當(dāng)我們只有生產(chǎn)者和消費(fèi)者都只有一個(gè)時(shí),大多數(shù)測(cè)試結(jié)果表明moodycamel::ConcurrentQueue的性能是最好的,大概比queue with std::mutex高出10%~50%左右的性能。boost::lockfree::queue比queue with std::mutex的性能只能高出一點(diǎn)點(diǎn)。由于我們的實(shí)現(xiàn)中,必須要求能夠使用多生產(chǎn)者的寫入,所以并沒(méi)有測(cè)試boost中專門的單生產(chǎn)者單消費(fèi)者的無(wú)鎖隊(duì)列boost::lockfree::spsc_queue,在這種場(chǎng)景下,boost稍稍有些吃虧,但并不影響整體測(cè)試結(jié)果及結(jié)論。
  • 當(dāng)我們有多個(gè)生產(chǎn)者線程和一個(gè)消費(fèi)者線程時(shí),boost::lockfree::queue的性能比queue with std::mutex高出75%~150%左右。 moodycamel::ConcurrentQueue的性能最好,大概比boost::lockfree::queue高出25%~100%,比queue with std::mutex高出100%~500%。當(dāng)生產(chǎn)者線程越多,也就是鎖沖突概率越大時(shí),moodycamel::ConcurrentQueue的性能優(yōu)勢(shì)體現(xiàn)得更加明顯。
  • 因此,上述對(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)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。