Chris_M_Thomasson

Simple mutex benchmark...

Feb 13th, 2019
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.70 KB | None | 0 0
  1. /* Simple, crude mutex test
  2.    by: Chris M. Thomasson
  3. __________________________________________*/
  4.  
  5.  
  6.  
  7. #include <thread>
  8. #include <atomic>
  9. #include <mutex>
  10. #include <condition_variable>
  11. #include <iostream>
  12. #include <functional>
  13. #include <cassert>
  14. #include <cstdlib>
  15. #include <ctime>
  16.  
  17.  
  18. #define THREADS 16UL
  19. #define ITERS 10000000UL
  20. #define COUNT (THREADS * ITERS)
  21.  
  22.  
  23. // undefine to test std::mutex
  24. #define CT_TEST_FAST_MUTEX 1
  25.  
  26.  
  27. // bin-sema
  28. struct ct_auto_reset_event
  29. {
  30.     bool m_state;
  31.     std::mutex m_mutex;
  32.     std::condition_variable m_cond;
  33.  
  34.     ct_auto_reset_event() : m_state(false) {}
  35.  
  36.     void signal()
  37.     {
  38.         std::unique_lock<std::mutex> lock(m_mutex);
  39.         m_state = true;
  40.         m_cond.notify_one();
  41.     }
  42.  
  43.     void wait()
  44.     {
  45.         std::unique_lock<std::mutex> lock(m_mutex);
  46.         while (m_state == false) m_cond.wait(lock);
  47.         m_state = false; // auto-reset
  48.     }
  49. };
  50.  
  51.  
  52. // just a layer over an auto-reset event
  53. struct ct_fast_mutex
  54. {
  55.     std::atomic<unsigned int> m_state;
  56.     ct_auto_reset_event m_waitset;
  57.  
  58.     ct_fast_mutex() : m_state(0) {}
  59.  
  60.     void lock()
  61.     {
  62.         if (m_state.exchange(1, std::memory_order_acquire))
  63.         {
  64.             while (m_state.exchange(2, std::memory_order_acquire))
  65.             {
  66.                 m_waitset.wait();
  67.             }
  68.         }
  69.     }
  70.  
  71.     void unlock()
  72.     {
  73.         if (m_state.exchange(0, std::memory_order_release) == 2)
  74.         {
  75.             m_waitset.signal();
  76.         }
  77.     }
  78. };
  79.  
  80.  
  81. struct ct_shared
  82. {
  83.     std::atomic<unsigned long> m_state;
  84.  
  85. #if defined (CT_TEST_FAST_MUTEX)
  86.     ct_fast_mutex m_std_mutex;
  87. #else
  88.     std::mutex m_std_mutex;
  89. #endif
  90.  
  91.     ct_shared() : m_state(0) {}
  92. };
  93.  
  94.  
  95. void ct_thread(ct_shared& shared, std::size_t index)
  96. {
  97.     for (unsigned int i = 0; i < ITERS; ++i)
  98.     {
  99.         shared.m_std_mutex.lock();
  100.         if (i % 256 == 0) std::this_thread::yield();
  101.         shared.m_state += 1;
  102.         shared.m_std_mutex.unlock();
  103.     }
  104. }
  105.  
  106.  
  107. int main()
  108. {
  109.     ct_shared shared;
  110.  
  111.     {
  112.         std::thread threads[THREADS];
  113.  
  114.         std::clock_t start = std::clock();
  115.  
  116.         for (std::size_t i = 0; i < THREADS; ++i)
  117.         {
  118.             threads[i] = std::thread(ct_thread, std::ref(shared), i);
  119.         }
  120.  
  121.         for (std::size_t i = 0; i < THREADS; ++i)
  122.         {
  123.             threads[i].join();
  124.         }
  125.  
  126.         std::clock_t diff = clock() - start;
  127.  
  128.         unsigned long msec = diff * 1000 / CLOCKS_PER_SEC;
  129.  
  130.         std::cout << "msec = " << msec << "\n";
  131.     }
  132.  
  133.     std::cout << "shared.m_state = " << shared.m_state << "\n";
  134.     std::cout << "\n\nFin!\n";
  135.  
  136.     assert(shared.m_state == COUNT);
  137.  
  138.     return 0;
  139. }
Advertisement
Add Comment
Please, Sign In to add comment