for循环内外的互斥锁速度差异
Posted
技术标签:
【中文标题】for循环内外的互斥锁速度差异【英文标题】:Mutex lock speed difference inside and outisde the foor loop 【发布时间】:2017-05-22 18:12:51 【问题描述】:我对在 for 循环内部和外部使用互斥锁 lock() 和 unlock() 的速度不同感到困惑。我得到了一个全局变量值和一个将其递增 1000000 次的函数。该函数由 5 个线程并行运行。我测量了经过的时间并得到了这些结果:
mutex.lock();
for(int i = 0; i < 1000000; i++)
value++;
mutex.unlock();
0.160921 秒
和:
for(int i = 0; i < 1000000; i++)
mutex.lock();
value++;
mutex.unlock();
2.10521 秒
我假设使用第二个内部互斥体安排控制太精细了,并且在线程切换之间花费了大量时间?还是有别的?
【问题讨论】:
【参考方案1】:锁定和解锁互斥体需要一些时间。具体来说,它比增加一个整数需要更多的时间。您的第二个示例只是测试锁定/解锁速度,并且还增加了任务切换开销,因为在互斥锁解锁的任何时候,不同的线程都可以接管。
首先,编译器可以通过一个加法来替换循环。而且因为线程的全部功能都被互斥体覆盖,所以没有并行执行;除了一个线程之外的所有线程都被阻塞,直到一个线程的循环完成,这意味着代码相当于在一个线程上连续循环五次。
这与细粒度锁定与粗粒度锁定关系不大。这些策略是关于您是否拥有覆盖大量资源的少量锁,或者覆盖少量资源的大量锁。您只有一种资源(全局 int),因此无需做出决定。
相反,这是关于是否仅将互斥锁锁定一小段时间,从而在其余时间将其打开以供其他线程工作,或者将其锁定更长的时间以避免开销,但会降低并行度。但是,由于您的线程除了访问受保护的资源之外什么都不做,因此没有“其余时间”。您的问题(将整数递增 5000000 次)一开始就没有内在的并行性,因此没有什么可供多线程利用的。
【讨论】:
以上是关于for循环内外的互斥锁速度差异的主要内容,如果未能解决你的问题,请参考以下文章