std::lock_guard 怎么可能比 std::mutex::lock() 快?
How can std::lock_guard be faster than std::mutex::lock()?
我和一位同事争论 lock_guard,他提出 lock_guard 可能比 mutex::lock() / mutex::unlock() 慢,因为实例化和取消实例化 class lock_guard.
的成本
然后我创建了这个简单的测试,令人惊讶的是,带有 lock_guard 的版本比带有 mutex::lock() / mutex::unlock()[=14 的版本快几乎两倍=]
#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
.
你在计时 DEBUG 吗?
编辑:
此外,在查看 RELEASE
反汇编时,我注意到 mutex
方法保存在两个注册表中:
010F104E mov edi,dword ptr [__imp___Mtx_lock (010F3060h)]
010F1054 xor esi,esi
010F1056 mov ebx,dword ptr [__imp___Mtx_unlock (010F3054h)]
并从 func1
和 func2
以相同的方式调用:
010F1067 call edi
....
010F107F call ebx
我和一位同事争论 lock_guard,他提出 lock_guard 可能比 mutex::lock() / mutex::unlock() 慢,因为实例化和取消实例化 class lock_guard.
的成本然后我创建了这个简单的测试,令人惊讶的是,带有 lock_guard 的版本比带有 mutex::lock() / mutex::unlock()[=14 的版本快几乎两倍=]
#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
.
你在计时 DEBUG 吗?
编辑:
此外,在查看 RELEASE
反汇编时,我注意到 mutex
方法保存在两个注册表中:
010F104E mov edi,dword ptr [__imp___Mtx_lock (010F3060h)]
010F1054 xor esi,esi
010F1056 mov ebx,dword ptr [__imp___Mtx_unlock (010F3054h)]
并从 func1
和 func2
以相同的方式调用:
010F1067 call edi
....
010F107F call ebx