Vittorio Romeo
Vittorio Romeo

Reputation: 93324

std::mutex and std::condition_variable construction overhead vs heap allocation

I have a task class that I need to be movable. I have around 10-15 tasks that are contained in a task_storage parent class. Inside task::execute() I need to wait for an atomic variable to reach zero:

void task::execute()
{
    for_subtasks([this]
        {
            thread_pool.post([this]
                {
                    this->do_work();

                    // Atomic counter.
                    --(this->_remaining_subtasks);
                });
        });

    // wait for `_remaining_subtasks == 0`
}

I have thought of three alternatives to wait for _remaining_subtasks == 0 while keeping task movable:

  1. Use a while(...){ sleep(1); } busy waiting loop.

  2. Construct and use an std::mutex and an std::condition_variable inside the function.

    void task::execute()
    {
        std::mutex m;
        std::condition_variable cv;
    
        for_subtasks(/* ... */);
    
        std::unique_lock<std::mutex> l(m);
        cv.wait(l, [this]{ return this->_remaining_subtasks == 0; });
    }
    
  3. Store an std::unique_ptr<std::mutex> and an std::unique_ptr<std::condition_variable> inside task as fields. This would allow task to be movable, but also introduce indirection to access the synchronization primitives.

    void task::execute()
    {
        for_subtasks(/* ... */);
    
        std::unique_lock<std::mutex> l(*this->_m);
        this->_cv.wait(l, [this]{ return this->_remaining_subtasks == 0; });
    }
    

I don't intend on using busy waiting. I tried profiling the fastest solution between 2 and 3 but could not get any meaningful result.

Is the construction overhead for std::mutex and std::condition_variable significant? Or would the heap allocations/accesses be slower?

Upvotes: 0

Views: 1024

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136425

Is the construction overhead for std::mutex and std::condition_variable significant? Or would the heap allocations/accesses be slower?

In both cases constructors must be invoked. The difference is where the memory is allocated: static storage, stack or heap. Heap allocation is the slowest.

On Linux and POSIX compatible systems, std::mutex and std::condition_variable are thin wrappers over POSIX pthread_mutex_t and pthread_cond_t structures. Initializing these structures involves setting member variables of fundamental types and no calls. In other words, the construction is cheap.

Upvotes: 1

Related Questions