私は同僚とlock_guardについて議論しており、彼は、lock_guardクラスのインスタンス化とインスタンス化のコストのために、lock_guardはmutex :: lock()/ mutex :: unlock()よりもおそらく遅いと提案しました。
次に、この簡単なテストを作成しました。驚いたことに、lock_guardを使用したバージョンは、mutex :: lock()/ mutex :: unlock()を使用したバージョンよりもほぼ2倍高速です。
#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
コンパイラフラグを投稿してください...ベンチマークは最適化レベルによって異なります...
—
Macmade
プロヒント:このような測定を行って、必ずそれだけで問題を引き起こして風邪データ/命令をでないようにするためのスワップ:coliru.stacked-crooked.com/a/81f75a1ab52cb1cc
—
NathanOliver
このような測定を行う際に役立つもう1つのことは、全体をより大きなループに入れて、測定セット全体を実行する(たとえば、各実行を20回)ようにすることです。通常、後の測定値は実際に意味のあるものになります。それまでに、キャッシュは長期的に見られる可能性のある動作に落ち着いているからです。
—
Mark Phaedrus
場合でも、
—
フランソワアンドリュー
std::lock_guard
あなたは速度ゲインを使用しての他の利点無効にしないこと、それはパフォーマンスの面で重要なことを証明できない限り少し遅く、だったstd::lock_guard
(主にRAIIを)。g++
投げることができるもの、または将来さらに複雑になる可能性のあるものに変更される可能性があるものがある場合は、ロックを所有するために何らかのオブジェクトを使用する必要があります。