2016-05-06 8 views
0

私はmutexを使ってブースト侵入リストをラップし、それをスレッドセーフにしてプロデューサ/コンシューマキューとして使用しました。スレッドセーフブースト侵入リストが遅い

しかし、ウィンドウ(MSVC 14)ではプロファイリング後、実際には遅いですが、主にpush()waint_and_pop()メソッドの95%がアイドル状態です。

私は1つのプロデューサと2つのプロデューサ/コンシューマスレッドしか持っていません。

これをより速くするための提案はありますか?

#ifndef INTRUSIVE_CONCURRENT_QUEUE_HPP 
#define INTRUSIVE_CONCURRENT_QUEUE_HPP 
#include <thread> 
#include <mutex> 
#include <condition_variable> 
#include <boost/intrusive/list.hpp> 

using namespace boost::intrusive; 

template<typename Data> 
class intrusive_concurrent_queue 
{ 
protected: 
    list<Data, constant_time_size<false> > the_queue; 
    mutable std::mutex the_mutex; 
    std::condition_variable the_condition_variable; 

public: 
    void push(Data * data) 
    { 
     std::unique_lock<std::mutex> lock(the_mutex); 
     the_queue.push_back(*data); 
     lock.unlock(); 
     the_condition_variable.notify_one(); 
    } 

    bool empty() const 
    { 
     std::unique_lock<std::mutex> lock(the_mutex); 
     return the_queue.empty(); 
    } 

    size_t unsafe_size() const 
    { 
     return the_queue.size(); 
    } 

    size_t size() const 
    { 
     std::unique_lock<std::mutex> lock(the_mutex); 
     return the_queue.size(); 
    } 

    Data* try_pop() 
    { 
     Data* popped_ptr; 
     std::unique_lock<std::mutex> lock(the_mutex); 
     if(the_queue.empty()) 
     { 
      return nullptr; 
     } 

     popped_ptr= & the_queue.front(); 
     the_queue.pop_front(); 
     return popped_ptr; 
    } 

    Data* wait_and_pop(const bool & exernal_stop = false) 
    { 
     Data* popped_ptr; 
     std::unique_lock<std::mutex> lock(the_mutex); 

     the_condition_variable.wait(lock,[&]{ return ! (the_queue.empty() | exernal_stop) ; }); 

     if (exernal_stop){ 
      return nullptr; 
     } 

     popped_ptr=&the_queue.front(); 
     the_queue.pop_front(); 
     return popped_ptr; 
    } 

    intrusive_concurrent_queue<Data> & operator=(intrusive_concurrent_queue<Data>&& origin)  
     { 
     this->the_queue = std::move(the_queue); 
     return *this; 
     } 

}; 

#endif // !INTRUSIVE_CONCURRENT_QUEUE_HPP 

答えて

1

ロックをメソッドから削除し、データ構造全体をロックすることをお試しください。

+0

これは解決策である可能性があります。ロックはループのすべての反復で取得されるか、またはいずれも取得されません。私は共有ミューテックスで何かを理解しようとします。 – xvan

関連する問題