#include #include #include #include #include using namespace std; // In this version, rather than synchronize the data, // we synchronize execution of the code, in particular, // the increase_mutex method mutex globalMutex; // mutex to control exeuction of method atomic atomic_counter (0); int unsync_counter = 0; void increase_atomic(int n) { for (int i=0; i lock(globalMutex); // safe mutex acquistion for (int i=0; i lock(globalMutex); // safe mutex acquistion ++unsync_counter; } } void waitForThreads(vector &threads) { cout << "wait for all threads..." << endl; int joined = 0; for (auto & th : threads) { th.join(); joined++; } threads.clear(); cout << "join'ed " << joined << " threads" << endl; } int main (int argc, char *argv[]) { vector threads; auto t1 = chrono::high_resolution_clock::now(); cout << endl << "increase atomic counter with 10 threads..." << endl; for (int i=1; i<=10; ++i) threads.push_back(thread(increase_atomic, 10000000)); waitForThreads(threads); cout << "atomic counter: " << atomic_counter << '\n'; auto t2 = chrono::high_resolution_clock::now(); cout << chrono::duration_cast(t2 - t1).count() << " microseconds" << endl; t1 = chrono::high_resolution_clock::now(); cout << endl << "increase unsynchronized counter with 10 threads, coarse grained..." << endl; for (int i=1; i<=10; ++i) threads.push_back(thread(increase_mutex_coarseGrained, 10000000)); waitForThreads(threads); cout << "unsync counter: " << unsync_counter << '\n'; t2 = chrono::high_resolution_clock::now(); cout << chrono::duration_cast(t2 - t1).count() << " microseconds" << endl; unsync_counter = 0; t1 = chrono::high_resolution_clock::now(); cout << endl << "increase unsynchronized counter with 10 threads, fine grained..." << endl; for (int i=1; i<=10; ++i) threads.push_back(thread(increase_mutex_fineGrained, 10000000)); waitForThreads(threads); cout << "unsync counter: " << unsync_counter << '\n'; t2 = chrono::high_resolution_clock::now(); cout << chrono::duration_cast(t2 - t1).count() << " microseconds" << endl; return 0; }