std :: lock_guard가 std :: mutex :: lock ()보다 어떻게 빠를 수 있습니까?


9

나는 동료와 lock_guard에 대해 논쟁하고 있었고, lock_guard는 클래스 lock_guard를 인스턴스화하고 unistantiate하는 비용 때문에 아마도 mutex :: lock () / mutex :: unlock ()보다 느릴 것이라고 제안했다.

그런 다음이 간단한 테스트를 작성했으며 놀랍게도 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

누군가 왜 이것이 어떻게 될 수 있는지 명확히 할 수 있습니까?


2
몇 번이나 측정 했습니까?
artm

7
컴파일러 플래그를 게시하십시오 ... 벤치마킹은 최적화 수준에 따라 다릅니다 ...
Macmade

10
프로 팁 :이 같은 측정을 수행 할 때, 확인하는 순서를 바꿀 그것입니다뿐만 아니라 감기 데이터 / 문제의 원인 설명 : coliru.stacked-crooked.com/a/81f75a1ab52cb1cc
NathanOliver

2
이와 같이 측정 할 때 도움이되는 또 다른 사항 : 전체 측정을 ​​더 큰 루프에 배치하여 전체 측정 세트 (예 : 각 실행마다 20 회)를 실행하십시오. 일반적으로 이후 측정은 실제로 의미있는 측정이 될 것입니다. 캐시는 장기적으로 발생할 수있는 모든 동작으로 설정 되었기 때문입니다.
Mark Phaedrus

2
std::lock_guard속도가 조금 느리 더라도 성능 측면에서 중요하다는 것을 입증 할 수 없다면, 그 속도 증가는 std::lock_guard(주로 RAII) 사용의 다른 이점을 무효화하지 않습니다 . 경우에 g++던지거나 잠재적으로 더 거의 미래에 복잡한 무언가로 변경 될 수 있습니다 아무것도 수있는 일이다 잠금을 소유하는 객체의 일종을 사용하는가.
François Andrieux

답변:


6

릴리스 빌드는 두 버전 모두에 대해 동일한 결과를 생성합니다.

DEBUG을위한 ~ 33 % 더 긴 시간 빌드 쇼 func2; 나는 분해한다는 점에서 볼의 차이 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)]  

모두에서 같은 방법으로 전화 func1func2:

010F1067  call        edi  
....
010F107F  call        ebx  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.