From 543a2948a7cfba8b822118f5faac3d3c527b4749 Mon Sep 17 00:00:00 2001 From: Vahagn Khachatryan Date: Thu, 20 Jun 2013 17:59:54 +0500 Subject: [PATCH] A thread scheduler test and a similar test for TBB. --- _.cpp | 6 +++ cf5-opt.vim | 40 +++++++++++++++ tbb_task_scheduler_init.cpp | 44 +++++++++++++++++ test_placement_new.cpp | 31 ++++++++++++ thread_scheduler.cpp | 97 +++++++++++++++++++++++++++++++++++++ 5 files changed, 218 insertions(+) create mode 100644 cf5-opt.vim create mode 100644 tbb_task_scheduler_init.cpp create mode 100644 test_placement_new.cpp create mode 100644 thread_scheduler.cpp diff --git a/_.cpp b/_.cpp index 5835823..d089037 100644 --- a/_.cpp +++ b/_.cpp @@ -1,3 +1,9 @@ +/* Check cf5-opt.vim defs. +VIM: let g:lcppflags="-std=c++11 -O2" +VIM: let g:cppflags=g:boost.g:tbb.g:tbbmalloc.g:tbbmproxy +VIM: let g:ldlibpath=g:boostld.g:tbbld +VIM: let g:cf5output=0 +*/ #include #include diff --git a/cf5-opt.vim b/cf5-opt.vim new file mode 100644 index 0000000..53bebb8 --- /dev/null +++ b/cf5-opt.vim @@ -0,0 +1,40 @@ +function! s:SetUpLibrariesLinux() + " + " the root of all 3pty libraries + " + let g:srcdir=$HOME . "/src" + " + " BOOST + " + let g:boostdir=g:srcdir . "/boost_1_53_0" + let g:boostinc=g:boostdir + let g:boostlib=g:boostdir . "/lib-amd64/lib" + let g:boostld=":".g:boostlib + let g:boost=" -I".g:boostinc." -L".g:boostlib" + " + " Intel TBB + " + let g:tbbdir=g:srcdir . "/tbb41_20130116oss" + let g:tbbinc=g:tbbdir . "/include" + let g:tbblib=g:tbbdir . "/lib/intel64/cc4.1.0_libc2.4_kernel2.6.16.21" + let g:tbbld=":".g:tbblib + let g:tbb=" -I".g:tbbinc." -L".g:tbblib." -ltbb" + let g:tbbmalloc=" -ltbbmalloc" + let g:tbbmproxy=" -ltbbmalloc_proxy" + +endfunction + +function! s:SetUpLibrariesWindows() + call s:SetUpLibrariesLinux() +endfunction + +function! SetUpLibraries() + if has("win32") || has("win64") + call s:SetUpLibrariesWindows() + else + call s:SetUpLibrariesLinux() + endif +endfunction + +call SetUpLibraries() + diff --git a/tbb_task_scheduler_init.cpp b/tbb_task_scheduler_init.cpp new file mode 100644 index 0000000..c236f39 --- /dev/null +++ b/tbb_task_scheduler_init.cpp @@ -0,0 +1,44 @@ +/* Check cf5-opt.vim defs. +VIM: let g:lcppflags="-std=c++11 -O2" +VIM: let g:cppflags=g:tbb." -ltbbmalloc -ltbbmalloc_proxy" +VIM: let g:ldlibpath=g:tbbld +*/ +#include +#include +#include +#include +#include +#include + +int main ( void ) +{try{ + + std::vector v(1024*1024*1024); + tbb::task_scheduler_init init3(20); + tbb::task_scheduler_init init(10); + tbb::task_scheduler_init init2(1); + tbb::enumerable_thread_specific count; + tbb::parallel_for_each( v.begin(), v.end(), [&count](int& v){ + ++count.local(); + }); + + int i = 0; + for ( int c : count ) + { + std::cout << "Thread: " << ++i << " counted " << c << std::endl; + } + return 0; +} +catch ( const std::exception& e ) +{ + std::cerr << std::endl + << "std::exception(\"" << e.what() << "\")." << std::endl; + return 2; +} +catch ( ... ) +{ + std::cerr << std::endl + << "unknown exception." << std::endl; + return 1; +}} + diff --git a/test_placement_new.cpp b/test_placement_new.cpp new file mode 100644 index 0000000..b1dddc0 --- /dev/null +++ b/test_placement_new.cpp @@ -0,0 +1,31 @@ +#include +#include +#include + + +void * operator new ( size_t s, const std::string& str ) +{ + std::cout << str << std::endl; + return malloc( s ); +} + + +int main ( void ) +{try{ + + int * i = new (std::string("Hello")) int; + return 0; +} +catch ( const std::exception& e ) +{ + std::cerr << std::endl + << "std::exception(\"" << e.what() << "\")." << std::endl; + return 2; +} +catch ( ... ) +{ + std::cerr << std::endl + << "unknown exception." << std::endl; + return 1; +}} + diff --git a/thread_scheduler.cpp b/thread_scheduler.cpp new file mode 100644 index 0000000..a5f8ea1 --- /dev/null +++ b/thread_scheduler.cpp @@ -0,0 +1,97 @@ +/* Check cf5-opt.vim defs. +VIM: let g:lcppflags="-std=c++11 -O2 -pthread -D_GLIBCXX_USE_SCHED_YIELD" +VIM: let g:cf5output=0 +*/ + +/* + * Conclusion: + * Linux RH 5.7 scheduler affiliates threads to a core. As a result + * if 20 threads are working on 16 core machine then 12 of them work + * 100% of the time and the 8 are working only 50% of the time. + * 34 thread case also was tested and the result is 28 threads work 50% + * of the time and 6 threads work 33% of the time. + * This same effect is visible in Intel TBB. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void busy_wait() +{ + for ( volatile int j = 0; j < 10000; ++j ); + // Actually this doesn't matter. Commented or uncommented the result + // is the same. + std::this_thread::yield(); +} + +int main ( void ) +{try{ + + const int n = 20; + std::atomic last_id(0); + + typedef long long work_type; + const work_type wamount = 1024L*1024L*10; + const work_type wslot = 1; + std::atomic last_work(0); + + std::vector threads; + threads.reserve(n); + +// std::condition_variable cv; + std::mutex m; + m.lock(); + + for ( int i=0; i < n; ++i ) + { + threads.push_back( std::thread( [&]() + { + int id = last_id++; + { + std::unique_lock ul(m); + // cv.wait(ul); + } + work_type c = 0; + while( true ) + { + work_type w = atomic_fetch_add( &last_work, wslot ); + if ( w >= wamount ) + break; + c += wslot; + busy_wait(); + } + std::stringstream ss; + ss << "Thread: " << std::setw(2) << id + << " counted " << std::setw(15) << c + << std::endl; + std::cout << ss.str(); + })); + } + + m.unlock(); +// cv.notify_all(); + + for ( std::thread& t : threads ) + t.join(); + + return 0; +} +catch ( const std::exception& e ) +{ + std::cerr << std::endl + << "std::exception(\"" << e.what() << "\")." << std::endl; + return 2; +} +catch ( ... ) +{ + std::cerr << std::endl + << "unknown exception." << std::endl; + return 1; +}} +