std::mutex 和 std::condition_variable 构造开销与堆分配
std::mutex and std::condition_variable construction overhead vs heap allocation
我有一个 task
class 需要移动。我有大约 10-15 个任务包含在 task_storage
父 class 中。在 task::execute()
内部,我需要等待一个原子变量达到零:
void task::execute()
{
for_subtasks([this]
{
thread_pool.post([this]
{
this->do_work();
// Atomic counter.
--(this->_remaining_subtasks);
});
});
// wait for `_remaining_subtasks == 0`
}
我想到了三种替代方法来等待 _remaining_subtasks == 0
,同时保持 task
可移动:
使用 while(...){ sleep(1); }
忙等待循环。
在函数内部构造并使用一个 std::mutex
和一个 std::condition_variable
。
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; });
}
在 task
中存储一个 std::unique_ptr<std::mutex>
和一个 std::unique_ptr<std::condition_variable>
作为字段。这将允许 task
可移动,但也会引入间接访问同步原语。
void task::execute()
{
for_subtasks(/* ... */);
std::unique_lock<std::mutex> l(*this->_m);
this->_cv.wait(l, [this]{ return this->_remaining_subtasks == 0; });
}
我不打算使用忙等待。我尝试分析 2 和 3 之间最快的解决方案,但无法获得任何有意义的结果。
std::mutex
和 std::condition_variable
的构造开销显着吗? 或者堆 allocations/accesses 会更慢吗?
Is the construction overhead for std::mutex and std::condition_variable significant? Or would the heap allocations/accesses be slower?
在这两种情况下都必须调用构造函数。不同之处在于分配内存的位置:静态存储、堆栈或堆。堆分配是最慢的。
在 Linux 和 POSIX 兼容系统上,std::mutex
和 std::condition_variable
是 POSIX pthread_mutex_t
和 [=13= 的精简包装器] 结构。初始化这些结构涉及设置基本类型的成员变量并且没有调用。换句话说,建造成本低。
我有一个 task
class 需要移动。我有大约 10-15 个任务包含在 task_storage
父 class 中。在 task::execute()
内部,我需要等待一个原子变量达到零:
void task::execute()
{
for_subtasks([this]
{
thread_pool.post([this]
{
this->do_work();
// Atomic counter.
--(this->_remaining_subtasks);
});
});
// wait for `_remaining_subtasks == 0`
}
我想到了三种替代方法来等待 _remaining_subtasks == 0
,同时保持 task
可移动:
使用
while(...){ sleep(1); }
忙等待循环。在函数内部构造并使用一个
std::mutex
和一个std::condition_variable
。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; }); }
在
task
中存储一个std::unique_ptr<std::mutex>
和一个std::unique_ptr<std::condition_variable>
作为字段。这将允许task
可移动,但也会引入间接访问同步原语。void task::execute() { for_subtasks(/* ... */); std::unique_lock<std::mutex> l(*this->_m); this->_cv.wait(l, [this]{ return this->_remaining_subtasks == 0; }); }
我不打算使用忙等待。我尝试分析 2 和 3 之间最快的解决方案,但无法获得任何有意义的结果。
std::mutex
和 std::condition_variable
的构造开销显着吗? 或者堆 allocations/accesses 会更慢吗?
Is the construction overhead for std::mutex and std::condition_variable significant? Or would the heap allocations/accesses be slower?
在这两种情况下都必须调用构造函数。不同之处在于分配内存的位置:静态存储、堆栈或堆。堆分配是最慢的。
在 Linux 和 POSIX 兼容系统上,std::mutex
和 std::condition_variable
是 POSIX pthread_mutex_t
和 [=13= 的精简包装器] 结构。初始化这些结构涉及设置基本类型的成员变量并且没有调用。换句话说,建造成本低。