std::lock_guard 怎么可能比 std::mutex::lock() 更快?

How can std::lock_guard be faster than std::mutex::lock()?

本文关键字:std lock 更快 怎么可能 guard mutex      更新时间:2023-10-16

我和一位同事争论了大约lock_guard,他提出lock_guard可能比mutex::lock((/mutex::unlock((慢,因为实例化和取消类lock_guard的成本。

然后我创建了这个简单的测试,令人惊讶的是,带有 lock_guard 的版本几乎比带有 mutex::lock((/mutex::unlock(( 的版本快两倍

#include <iostream>
#include <mutex>
#include <chrono>
std::mutex m;
int g = 0;
void func1()
{
m.lock();
g++;
m.unlock();
}
void func2()
{
std::lock_guard<std::mutex> lock(m);
g++;
}
int main()
{
auto t = std::chrono::system_clock::now();
for (int i = 0; i < 1000000; i++)
{
func1();
}
std::cout << "Take: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - t).count() << " ms" << std::endl;
t = std::chrono::system_clock::now();
for (int i = 0; i < 1000000; i++)
{
func2();
}
std::cout << "Take: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - t).count() << " ms" << std::endl;
return 0;
}

我机器上的结果:

Take: 41 ms
Take: 22 ms

有人可以澄清为什么以及如何这样做吗?

发布版本为两个版本生成相同的结果。

DEBUG构建显示func2的时间延长了 ~33%;我在反汇编中看到的差异func2使用__security_cookie并调用@_RTC_CheckStackVars@8

你正在计时调试吗?

编辑: 此外,在查看RELEASE反汇编时,我注意到mutex方法保存在两个注册表中:

010F104E  mov         edi,dword ptr [__imp___Mtx_lock (010F3060h)]  
010F1054  xor         esi,esi  
010F1056  mov         ebx,dword ptr [__imp___Mtx_unlock (010F3054h)]  

并从func1func2中以相同的方式调用:

010F1067  call        edi  
....
010F107F  call        ebx