如果我们有如下代码示例:
if (letsDoThis) //bool
{
sharedVar++; // This is shared across other threads.
:
sharedVar++;
:
sharedVar++;
:
sharedVar++;
:
sharedVar++;
}
其中每个 :
大约是 10 行代码(没有缓慢的函数调用或任何东西)。编写代码以便在整个“if” block (好吧,if block 的内容)周围锁定一个互斥体,或者锁定和解锁每个单独的 sharedVar 用法会更快吗?
如果这是一个“视情况而定”类型的问题,那么哪种方法(也许作为经验法则)更好?
最后,您如何确定两者中哪一个在您的系统上运行得更快? - 跟踪工具真的会以有意义的方式向您显示有用的数据吗?
最佳答案
这取决于(在所有其他影响性能的因素中)
- 您有多少线程和核心(两者的最小值相关)
- 线程在该部分代码(以及锁定互斥体的其他部分)花费了多少时间
从单个线程的角度来看,多个锁定和解锁意味着额外的工作,并且 - 特别是在拥塞的情况下 - 相当昂贵/耗时,并且它可能会导致内核之间更多的缓存乒乓。所以会降低单线程的性能。但是,如果多次锁定和解锁减少了线程在每次迭代中持有互斥锁的总时间,那么这意味着您的程序中可以有更多的并行性,并且整体性能会随着线程和 CPU 内核的数量而更好地扩展。
这两种影响都可以忽略不计,两种影响都可能很重要,如果代码不在您程序的热路径中,那么一开始它可能并不重要。我认为,您唯一可以做的就是运行两种变体并测量整体吞吐量,以确定在您的情况下什么更好。如果您看不出有什么区别,为了简单起见,我可能会使用单锁和解锁(即使用 std::lock_guard
)。
然而,您应该问的一般问题是,如果您真的需要在线程之间进行如此多的同步,并且您是否必须多次同步:如果其他线程看不到共享状态的中间值(这如果它们不互相等待,你无论如何都无法保证),那你为什么不将共享状态上的所有操作组合起来,并在 block 的末尾使其成为一个单一的操作?
当然,如果您的共享状态确实只是一个整数,那么您应该只使用原子并完全摆脱互斥量。
关于c++ - 在一个代码块中多次互斥锁定一个变量,还是只锁定整个代码块,效率更高?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36443386/