std::lock_guard 如何比 std::mutex::lock() 更快?

Edu*_*des 10 c++ mutex

我和一位同事争论 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;
}
Run Code Online (Sandbox Code Playgroud)

我机器上的结果:

Take: 41 ms
Take: 22 ms
Run Code Online (Sandbox Code Playgroud)

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

Vla*_*ein 6

发布版本对两个版本产生相同的结果。

DEBUG构建示出了用于延长〜33%的时间func2; 我在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)]  
Run Code Online (Sandbox Code Playgroud)

并从func1和以相同的方式调用func2

010F1067  call        edi  
....
010F107F  call        ebx  
Run Code Online (Sandbox Code Playgroud)