boost::lock_guard 分配、构造函数和析构函数开销
boost::lock_guard allocation, constructor, and destructor overhead
我正在学习互斥锁,我发现,要使用锁守卫,每次迭代都必须为锁守卫分配内存,调用构造函数,然后调用析构函数。与永不超出范围的锁相比,这似乎是一个很大的开销。我明白锁卫的好处,但避开他们能节省多少时间?或者,换句话说,线程每次迭代的工作必须多小才能使锁保护开销显着?
prepare_data();
{
boost::lock_guard<boost::mutex> lock(mut);
data_ready=true;
}
cond.notify_one();
不需要分配。编译器可以准确地看到构造函数和析构函数的作用,并优化内存分配或对象初始化或调用特定构造函数或析构函数的需要。
可以看出构造函数只调用了互斥体的lock函数,析构函数只调用了unlock函数。 lock_guard
的地址从未被占用,因此不需要一个。
这是在 C++ 中推荐 RAII 的关键原因之一——它通常没有任何成本。
编译器很可能必须在堆栈上分配 space 以存储对 lock_guard
析构函数的互斥体的引用。它不太可能缓存它,因为 (a) locking/unlocking 互斥锁是外部函数调用,并且 (b) 函数强加了内存栅栏。但是 locking/unlocking 互斥锁的成本远大于与 lock_guard
相关的其他操作,因此没有实际理由避免它。此外,现代编译器在堆栈管理方面拥有非常有效的技术,为引用分配 space 实际上可能是空操作。
我正在学习互斥锁,我发现,要使用锁守卫,每次迭代都必须为锁守卫分配内存,调用构造函数,然后调用析构函数。与永不超出范围的锁相比,这似乎是一个很大的开销。我明白锁卫的好处,但避开他们能节省多少时间?或者,换句话说,线程每次迭代的工作必须多小才能使锁保护开销显着?
prepare_data();
{
boost::lock_guard<boost::mutex> lock(mut);
data_ready=true;
}
cond.notify_one();
不需要分配。编译器可以准确地看到构造函数和析构函数的作用,并优化内存分配或对象初始化或调用特定构造函数或析构函数的需要。
可以看出构造函数只调用了互斥体的lock函数,析构函数只调用了unlock函数。 lock_guard
的地址从未被占用,因此不需要一个。
这是在 C++ 中推荐 RAII 的关键原因之一——它通常没有任何成本。
编译器很可能必须在堆栈上分配 space 以存储对 lock_guard
析构函数的互斥体的引用。它不太可能缓存它,因为 (a) locking/unlocking 互斥锁是外部函数调用,并且 (b) 函数强加了内存栅栏。但是 locking/unlocking 互斥锁的成本远大于与 lock_guard
相关的其他操作,因此没有实际理由避免它。此外,现代编译器在堆栈管理方面拥有非常有效的技术,为引用分配 space 实际上可能是空操作。