为什么在vs2013中boost::mutex比std::mutex更快?

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 64位, 结果是:0.7020秒与2.1684秒,3.08倍。

boost :: mutex 将首先尝试 _interlockedbittestandset, 如果失败,则会使用大哥 WaitForSingleObject, 很容易理解。

看起来 VS2013 的 std :: mutex 更加复杂,我已经试图理解它,但我无法抓住重点, 为什么它如此复杂?有更快的方法吗?


您是否在两种情况下启用了优化构建(如果是 Visual Studio,则为发布构建)? - Paul R
当然,使用/O2优化的默认发布构建。 - amanjiang
2
好的 - 很好知道 - 你会惊讶于有多少性能问题只需启用编译器优化就可以轻松“修复”。 - Paul R
2
(瞎猜:MS 开发人员的知识 < Boost 维护者的知识?) - user529758
在VS2012中复制,boost:587毫秒,stl:1818毫秒。 - N A
3
Microsoft的std::mutex是基于Concurrency Runtime构建的。后者是操作系统原语的完全重写,强调协作式而不是抢占式线程。如果你的测试代表了在程序中使用std::mutex的方式,那么坚持使用Boost可能会更好。 - Hans Passant
2个回答

4
似乎stl::mutex只使用系统调用,这会带来极大的开销;但是boost::mutex程序化地实现了其部分功能,即尽可能避免使用系统调用,这就是在WaitForSingleObject之前检查try _interlockedbittestandset的原因。我不知道MS stl的实际内部情况,但我从操作系统课程的例子中看到了这样的性能差异。

1
测试仅测试在没有其他线程争用的情况下锁定未锁定的互斥量的条件。
假设互斥量已被锁定。在初始增强尝试后,线程旋转还是阻止会更好?这完全取决于应用程序。也许STL在重负载下表现更佳。
当需要高效互斥量时,值得探索一种无锁替代方案来实现相同的目标。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接