A thread scheduler test and a similar test for TBB.
This commit is contained in:
6
_.cpp
6
_.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 <iostream>
|
#include <iostream>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
|
|||||||
40
cf5-opt.vim
Normal file
40
cf5-opt.vim
Normal file
@@ -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()
|
||||||
|
|
||||||
44
tbb_task_scheduler_init.cpp
Normal file
44
tbb_task_scheduler_init.cpp
Normal file
@@ -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 <tbb/enumerable_thread_specific.h>
|
||||||
|
#include <tbb/task_scheduler_init.h>
|
||||||
|
#include <tbb/parallel_for_each.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <exception>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
int main ( void )
|
||||||
|
{try{
|
||||||
|
|
||||||
|
std::vector<int> 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<int> 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;
|
||||||
|
}}
|
||||||
|
|
||||||
31
test_placement_new.cpp
Normal file
31
test_placement_new.cpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include <malloc.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}}
|
||||||
|
|
||||||
97
thread_scheduler.cpp
Normal file
97
thread_scheduler.cpp
Normal file
@@ -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 <thread>
|
||||||
|
#include <vector>
|
||||||
|
#include <atomic>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
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<int> last_id(0);
|
||||||
|
|
||||||
|
typedef long long work_type;
|
||||||
|
const work_type wamount = 1024L*1024L*10;
|
||||||
|
const work_type wslot = 1;
|
||||||
|
std::atomic<work_type> last_work(0);
|
||||||
|
|
||||||
|
std::vector<std::thread> 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<std::mutex> 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;
|
||||||
|
}}
|
||||||
|
|
||||||
Reference in New Issue
Block a user