/* 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 perhaps. 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. * Looks RH 5.7 uses linux kernel 2.6.18 which has O(1) scheduler. * * Linux RH 6.0 has linux kernel 2.6.32 which has Ingo Molnár's the * "Completely Fair Scheduler". On that system the above mentioned is not * observed. */ #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 = 34; std::atomic last_id(0); typedef long long work_type; const work_type wamount = 1024L*1024L*40; 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; }}