日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

lockfree buffer test

發布時間:2025/4/9 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lockfree buffer test 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

性能測試(3): 對無鎖隊列boost::lockfree::queue和moodycamel::ConcurrentQueue做一個性能對比測試

版權聲明:本文為博主zieckey原創文章,轉載時請保留版權信息。 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項目中的EventLoop::QueueInLoop(...)函數來做這個性能測試。我們通過該函數能夠將一個仿函數執行體從一個線程調度到另一個線程中執行。這是一個典型的生產者和消費者問題。

我們用一個隊列來保存這種仿函數執行體。多個生產者線程向這個隊列寫入仿函數執行體,一個消費者線程從隊列中取出仿函數執行體來執行。為了保證隊列的線程安全問題,我們可以使用一個鎖來保護這個隊列,或者使用無鎖隊列機制來解決安全問題。EventLoop::QueueInLoop(...)函數通過通定義實現了三種不同模式的跨線程交換數據的隊列。

測試對象

  • evpp-v0.3.2
  • EventLoop::QueueInLoop(...)函數內的隊列的三種實現方式:
    • 帶鎖的隊列用std::vector和std::mutex來實現,具體的 gcc 版本為 4.8.2
    • boost::lockfree::queue from boost-1.53
    • moodycamel::ConcurrentQueue with commit c54341183f8674c575913a65ef7c651ecce47243
  • 測試環境

  • 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)
  • 測試方法

    測試代碼請參考https://github.com/Qihoo360/evpp/blob/master/benchmark/post_task/post_task6.cc. 在一個消費者線程中運行一個EventLoop對象loop_,多個生產者線程不停的調用loop_->QueueInLoop(...)方法將仿函數執行體放入到消費者的隊列中讓其消費(執行)。每個生產者線程放入一定總數(由運行參數指定)的仿函數執行體之后就停下來,等消費者線程完全消費完所有的仿函數執行體之后,程序退出,并記錄開始和結束時間。

    為了便于大家閱讀,現將相關代碼的核心部分摘錄如下。

    event_loop.h中定義了隊列:

    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(...)的具體實現:

    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 }

    ?

    我們進行了兩種測試:

  • 一個生產者線程投遞1000000個仿函數執行體到消費者線程中執行,統計總耗時。然后同樣的方法我們反復測試10次
  • 生產者線程分別是2/4/6/8/12/16/20,每個線程投遞1000000個仿函數執行體到消費者線程中執行,并統計總共耗時
  • 測試結論

  • 當我們只有生產者和消費者都只有一個時,大多數測試結果表明moodycamel::ConcurrentQueue的性能是最好的,大概比queue with std::mutex高出10%~50%左右的性能。boost::lockfree::queue比queue with std::mutex的性能只能高出一點點。由于我們的實現中,必須要求能夠使用多生產者的寫入,所以并沒有測試boost中專門的單生產者單消費者的無鎖隊列boost::lockfree::spsc_queue,在這種場景下,boost稍稍有些吃虧,但并不影響整體測試結果及結論。
  • 當我們有多個生產者線程和一個消費者線程時,boost::lockfree::queue的性能比queue with std::mutex高出75%~150%左右。 moodycamel::ConcurrentQueue的性能最好,大概比boost::lockfree::queue高出25%~100%,比queue with std::mutex高出100%~500%。當生產者線程越多,也就是鎖沖突概率越大時,moodycamel::ConcurrentQueue的性能優勢體現得更加明顯。
  • 因此,上述對比測試結論,就我們的evpp項目中的EventLoop的實現方式,我們推薦使用moodycamel::ConcurrentQueue來實現跨線程的數據交換。

    更詳細的測試數據,請參考下面的兩個圖表。

    縱軸是執行耗時,越低性能越高。

    圖1,生產者和消費者都只有一個,橫軸是測試的批次:

    圖2,生產者線程有多個,橫軸是生產者線程的個數,分別是2/4/6/8/12/16/20:

    其他的性能測試報告

    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

    最后

    報告中的圖表是使用gochart繪制的。

    非常感謝您的閱讀。如果您有任何疑問,請隨時在https://github.com/Qihoo360/evpp/issues跟我們討論。謝謝。

    轉載于:https://www.cnblogs.com/lvdongjie/p/9681536.html

    總結

    以上是生活随笔為你收集整理的lockfree buffer test的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。