【发布时间】:2021-12-27 14:25:37
【问题描述】:
在 Visual Studio 2022 中以发布模式运行以下内容:
#include <chrono>
#include <mutex>
#include <shared_mutex>
#include <iostream>
std::mutex mx;
std::shared_mutex smx;
constexpr int N = 100'000'000;
int main()
{
auto t1 = std::chrono::steady_clock::now();
for (int i = 0; i != N; i++)
{
std::unique_lock<std::mutex> l{ mx };
}
auto t2 = std::chrono::steady_clock::now();
for (int i = 0; i != N; i++)
{
std::unique_lock<std::shared_mutex> l{ smx };
}
auto t3 = std::chrono::steady_clock::now();
auto d1 = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
auto d2 = std::chrono::duration_cast<std::chrono::duration<double>>(t3 - t2);
std::cout << "mutex " << d1.count() << "s; shared_mutex " << d2.count() << "s\n";
std::cout << "mutex " << sizeof(mx) << " bytes; shared_mutex " << sizeof(smx) << " bytes \n";
}
输出如下:
mutex 2.01147s; shared_mutex 1.32065s
mutex 80 bytes; shared_mutex 8 bytes
为什么会这样?
出乎意料的是,功能更丰富的std::shared_mutex 比std::mutex 更快,而std::mutex 严格来说是其功能的一个子集。
【问题讨论】:
-
我在我的 Windows 1.2 Ghz 笔记本电脑上编写了我自己的与您类似的测量代码,简单的自旋锁在循环中严格工作
24 ns,std::mutex75-85 ns,std::shared_mutex @ 987654327@. -
@Arty,比自旋锁慢两倍——是预期的互斥锁性能。您的自旋锁在退出时使用
store和memory_order_release,您只需将其释放即可。但是互斥锁会执行一个互锁的获取操作,很可能是exchange,以查看是否需要通知某些等待线程。 (x86 有memory_order_release的廉价商店,但任何exchange都不便宜,甚至_relaxed) -
你看过代码了吗?你的问题到底是什么?您是否比较了两者支持的功能来解释它们的时间差异?或者是尺寸差异,如果您有手柄/身体分离,这根本不稀奇。
标签: c++ visual-c++ stdmutex