Eu estava discutindo com um colega sobre o lock_guard, e ele propôs que o lock_guard é provavelmente mais lento que o mutex :: lock () / mutex :: unlock () devido ao custo de instanciar e desestabilizar a classe lock_guard.
Então criei esse teste simples e, surpreendentemente, a versão com lock_guard é quase duas vezes mais rápida que a versão com 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;
}
Os resultados na minha máquina:
Take: 41 ms
Take: 22 ms
Alguém pode esclarecer por que e como isso pode ser?
std::lock_guard
sido um pouco mais lento, a menos que você possa provar que é importante em termos de desempenho, esse ganho de velocidade não invalidará os outros benefícios do usostd::lock_guard
(principalmente RAII). Seg++
houver algo que possa ser lançado ou algo que possa se transformar em algo potencialmente mais complicado no futuro, você quase precisará usar algum tipo de objeto para possuir o bloqueio.Respostas:
A compilação do release produz o mesmo resultado para as duas versões.
A
DEBUG
compilação mostra ~ 33% mais tempo parafunc2
; a diferença que vejo na desmontagem quefunc2
usa__security_cookie
e invoca@_RTC_CheckStackVars@8
.Você está cronometrando DEBUG?
EDIT: Além disso, ao analisar a
RELEASE
desmontagem, notei que osmutex
métodos foram salvos em dois registros:e chamou da mesma maneira de ambos
func1
efunc2
:fonte