A thread scheduler test and a similar test for TBB.
This commit is contained in:
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