Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@usagi
Created December 11, 2019 10:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save usagi/f717c0db3613ab8a7b6c30fb66e597b4 to your computer and use it in GitHub Desktop.
Save usagi/f717c0db3613ab8a7b6c30fb66e597b4 to your computer and use it in GitHub Desktop.
std::mutex vs. boost::mutex (1.71.0) vs. Windows CRITICAL_SECTION with VS2019 and Windows 10
// 以下は計測対象の仕組みを提供するヘッダー
#include <mutex>
#include <boost/thread/mutex.hpp>
#include <Windows.h>
// 以下は計測システムの実装用
#include <cmath>
#include <thread>
#include <boost/timer/timer.hpp>
#include <boost/math/constants/constants.hpp>
#include <string>
#include <iostream>
#include <iomanip>
int main()
{
using t = double;
constexpr auto thread_count = 8;
constexpr auto repeat_cout = 8;
auto load = [] ( auto& v, auto lock, auto unlock )
{
constexpr auto a = boost::math::constants::pi<t>();
constexpr auto d = 1 / a;
for ( auto n = 1'000'000; n; --n )
{
lock();
v = std::pow( v, v < a ? a : d );
unlock();
}
};
auto tester = [=] ( auto lock, auto unlock )
{
// 複数スレッドからロックして操作しようとする変数
auto v = boost::math::constants::e<t>();
// ロック状態で計算負荷スレッドを開始
lock();
std::vector< std::thread > threads;
threads.reserve( thread_count );
for ( auto n = thread_count; n; --n )
threads.emplace_back( std::thread( [&] { return load( v, lock, unlock ); } ) );
// 時間計測を開始してロック解除
auto timer = boost::timer::cpu_timer();
unlock();
// 負荷スレッドの完了を待つ
for ( auto& f : threads )
f.join();
timer.stop();
// 結果出力
std::clog << timer.format( 2, "wall=%w user=%u system=%s total(u+s)=%t p(t/w)=%p%" ) << " | caclulated value = " << v << "\n";
};
auto repeater = [=] ( auto task )
{
for ( auto n = repeat_cout; n; --n )
task();
};
std::clog
<< "[the Benchmark of the Windows Mutices]\n"
"_MSC_VER = " << _MSC_VER << "\n"
"_DEBUG = ("
#ifdef _DEBUG
"defined: DEBUG BUILD"
#else
"undefined: RELEASE BUILD"
#endif
")\n"
"_WIN32_WINNT = 0x" << std::hex << std::uppercase << std::setw(4) << std::setfill( '0' ) << _WIN32_WINNT << "\n"
;
// warm up
{
std::clog << "<warm up>\n";
repeater( [=] { tester( [] {}, [] {} ); } );
}
// std::mutex
{
std::clog << "<std::mutex>\n";
std::mutex m;
repeater( [&] { tester( [&] { m.lock(); }, [&] { m.unlock(); } ); } );
}
// boost::mutex
{
std::clog << "<boost::mutex>\n";
boost::mutex m;
repeater( [&] { tester( [&] { m.lock(); }, [&] { m.unlock(); } ); } );
}
// Windows CRITICAL_SECTION
{
std::clog << "<Windows CRITICAL_SECTION>\n";
CRITICAL_SECTION m;
auto pm = &m;
InitializeCriticalSection( pm );
repeater( [&] { tester( [=] { EnterCriticalSection( pm ); }, [=] { LeaveCriticalSection( pm ); } ); } );
DeleteCriticalSection( pm );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment