Потокобезопасный буст навязчивый список медленно

Я завел интрузивный список наддува мьютексом, чтобы сделать его потокобезопасным для использования в качестве очереди производителя / потребителя.

Но на Windows (MSVC 14) это очень медленно, после профилирования, 95% времени тратится без дела, в основном на push() а также waint_and_pop() методы.

У меня только 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 ответ

Попробуйте снять блокировку с методов и заблокировать всю структуру данных, когда вы что-то делаете с ней.

Другие вопросы по тегам