Created
December 11, 2019 10:17
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 以下は計測対象の仕組みを提供するヘッダー | |
#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