【发布时间】:2014-04-06 19:43:55
【问题描述】:
我有以下基准:https://gist.github.com/leifwalsh/10010580
基本上它会启动k 线程,然后每个线程使用自旋锁和std::mutex 执行大约1600 万/k 锁定/增量/解锁周期。在 OSX 上,std::mutex 在竞争时比自旋锁慢得多,而在 Linux 上它具有竞争力或更快。
OSX:
spinlock 1: 334ms
spinlock 2: 3537ms
spinlock 3: 4815ms
spinlock 4: 5653ms
std::mutex 1: 813ms
std::mutex 2: 38464ms
std::mutex 3: 44254ms
std::mutex 4: 47418ms
Linux:
spinlock 1: 305ms
spinlock 2: 1590ms
spinlock 3: 1820ms
spinlock 4: 2300ms
std::mutex 1: 377ms
std::mutex 2: 1124ms
std::mutex 3: 1739ms
std::mutex 4: 2668ms
处理器不同,但没有那么不同(OSX 是 Intel(R) Core(TM) i7-2677M CPU @ 1.80GHz,Linux 是 Intel(R) Core(TM) i5- 2500K CPU @ 3.30GHz),这似乎是库或内核问题。有人知道缓慢的根源吗?
为了澄清我的问题,我理解“有不同的互斥锁实现可以针对不同的事物进行优化,这不是问题,这是意料之中的”。这个问题是:导致这种情况的实际实施差异是什么?或者,如果是硬件问题(也许 macbook 上的缓存慢了很多),这也是可以接受的。
【问题讨论】:
-
移动 CPU 有 2 个内核和超线程(运行速度只有一半,但这可能不是问题)。台式机 CPU 有 4 个真正的内核。这似乎是一个非常很大的差异。
-
您链接到哪个标准 C++ 库? libstdc++ 还是 libc++?
-
osx 上的 libc++,linux 上的 libstdc++
-
最大的不同可能是在 MacOS X 上没有人关心。您的代码是用 Objective-C 编写的,对象属性的原子设置器很快,@synchronized 也很快。一直存在原子设置/添加/或操作。并且有可能代码没有针对病理情况进行优化,而是针对通常情况进行优化。
-
这几乎可以肯定主要是由于一个锁是公平的(即按 FIFO 顺序唤醒等待线程)而另一个不是。不过,在更新的操作系统版本上,无竞争的采集时间应该会好很多。 (虽然如果 Linux std::mutex 是 实际上是一个公平的锁,那是非常令人印象深刻的)
标签: c++ multithreading macos