12

今天我写了一些代码来测试互斥量的性能。

这是boost(1.54)版本,在vs2010上编译,O2优化:

boost::mutex m;
auto start = boost::chrono::system_clock::now();
for (size_t i = 0; i < 50000000; ++i) {
    boost::lock_guard<boost::mutex> lock(m);
}
auto end = boost::chrono::system_clock::now();
boost::chrono::duration<double> elapsed_seconds = end - start;
std::cout << elapsed_seconds.count() << std::endl;

这是标准版本,在 VS2013 上编译,也有 O2 优化:

std::mutex m;
auto start = std::chrono::system_clock::now();
for (size_t i = 0; i < 50000000; ++i) {
    std::lock_guard<std::mutex> lock(m);
}
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
std::cout << elapsed_seconds.count() << std::endl;

有点不同,但做同样的事情。我的 CPU 是 Intel Core i7-2600K,我的操作系统是 Windows 7 64bit,结果是:0.7020s vs 2.1684s,3.08 倍。

boost::mutex 会先尝试 _interlockedbittestandset ,如果失败了,大奶酪 WaitForSingleObject 会排在第二位,简单易懂。

VS2013 的 std::mutex 似乎要复杂得多,我已经尝试理解它但我不明白,为什么它这么复杂?有更快的方法吗?

4

2 回答 2

4

似乎stl::mutex可能只使用系统调用,这需要很多开销;但boost::mutex至少以编程方式实现了它的一些功能——即它尽可能避免系统调用,这将是try _interlockedbittestandset之前检查的原因WaitForSingleObject

我不知道 MS 的 stl 的实际内部结构,但我从操作系统类的示例中看到了这样的性能差异。

于 2013-10-23T05:34:44.860 回答
1

该测试仅测试锁定未锁定互斥体的条件,而没有来自其他线程的任何争用。

假设互斥锁被锁定。在最初的提升尝试之后,线程旋转或阻塞会更好吗?这真的完全取决于应用程序。也许 stl 在重负载下表现更好。

当时代需要高效的互斥体时,实现相同目标的无锁替代方案值得探索。

于 2014-12-16T18:16:55.443 回答