Std :: lock_guard nasıl std :: mutex :: lock () 'den daha hızlı olabilir?


9

Lock_guard hakkında bir meslektaşımla tartışıyordum ve sınıfın lock_guard örneğini oluşturup unistantiate nedeniyle lock_guard'ın mutex :: lock () / mutex :: unlock () 'den daha yavaş olduğunu önerdi.

Sonra bu basit testi oluşturdum ve şaşırtıcı bir şekilde, lock_guard olan sürüm mutex :: lock () / mutex :: unlock () sürümüne göre neredeyse iki kat daha hızlı

#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;
}

Makinemdeki sonuçlar:

Take: 41 ms
Take: 22 ms

Birisi bunun neden ve nasıl olabileceğini açıklığa kavuşturabilir mi?


2
ve ölçümlerinizi kaç kez yaptınız?
artm

7
Lütfen derleyici bayraklarınızı gönderin ... Kıyaslama optimizasyon seviyesine bağlı olacaktır ...
Macmade

10
Profesyonel İpucu: Bunun gibi ölçümler yaparken, soruna neden olan yalnızca soğuk veriler / talimatlar olmadığından emin olmak için siparişi değiştirin: coliru.stacked-crooked.com/a/81f75a1ab52cb1cc
NathanOliver

2
Bunun gibi ölçümler yaparken yardımcı olan başka bir şey: her şeyi daha büyük bir döngüye koyun, böylece tüm ölçüm setini çalıştırırsınız, örneğin, her çalışmadan 20 kez. Genellikle daha sonraki ölçümler gerçekten anlamlı olanlardır, çünkü o zamana kadar önbellek uzun vadede olabilecek davranışlara yerleşmiştir.
Mark Phaedrus

2
std::lock_guardBiraz daha yavaş olsa bile , performans açısından önemli olduğunu kanıtlayamazsanız, bu hız kazancı, kullanımın diğer faydalarını std::lock_guard(esas olarak RAII) geçersiz kılmaz . Eğer g++atmak veya potansiyel olarak daha neredeyse gelecekte karmaşık bir hale değişebilir şey bir şey olduğunu var kilidi kendi nesne çeşit kullanmak.
François Andrieux

Yanıtlar:


6

Sürüm derlemesi her iki sürüm için de aynı sonucu verir.

DEBUGİçin ~% 33 daha uzun bir zaman yapı gösterir func2; func2kullanan __security_cookieve çağıran demontajda gördüğüm fark @_RTC_CheckStackVars@8.

DEBUG zamanlaması mı yapıyorsunuz?

EDIT: Ayrıca, RELEASEsökme bakarken, mutexyöntemlerin iki kayıtlara kaydedildi fark ettim :

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

ve her ikisinden de aynı şekilde çağırdı func1ve func2:

010F1067  call        edi  
....
010F107F  call        ebx  
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.