• C++ mutex, atomic, CAS性能


    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. static uint64_t total_1 = 0;
    9. std::mutex mtx;
    10. void pred1(void)
    11. {
    12. for (uint64_t i = 0; i <= 100000000; i++) {
    13. mtx.lock();
    14. total_1 += i;
    15. mtx.unlock();
    16. }
    17. }
    18. void test1()
    19. {
    20. total_1 = 0;
    21. std::cout << "thread[" << std::this_thread::get_id() << "]-1 start...\n";
    22. auto start = std::chrono::steady_clock::now();
    23. std::thread t1(pred1);
    24. std::thread t2(pred1);
    25. t1.join();
    26. t2.join();
    27. auto end = std::chrono::steady_clock::now();
    28. std::chrono::duration<double> elapsed_seconds = end - start;
    29. std::cout << "test1(mutex/multi-thread) -> " << " total_1: " << total_1 << " elapsed time(ms): " << std::chrono::duration_cast(elapsed_seconds).count() << "ms\n";
    30. std::cout << "test1(mutex/multi-thread) -> " << " total_1: " << total_1 << " elapsed time(s): " << std::chrono::duration_cast(elapsed_seconds).count() << "s\n";
    31. }
    32. std::atomic_uint64_t total_2{ 0 };
    33. void pred2(void)
    34. {
    35. for (uint64_t i = 0; i <= 100000000; i++) {
    36. total_2 += i;
    37. }
    38. }
    39. void test2()
    40. {
    41. std::cout << "thread[" << std::this_thread::get_id() << "]-2 start...\n";
    42. auto start = std::chrono::steady_clock::now();
    43. std::thread t1(pred2);
    44. std::thread t2(pred2);
    45. t1.join();
    46. t2.join();
    47. auto end = std::chrono::steady_clock::now();
    48. std::chrono::duration<double> elapsed_seconds = end - start;
    49. std::cout << "test2(atomic/multi-thread) -> " << " total_2: " << total_2 << " elapsed time(ms): " << std::chrono::duration_cast(elapsed_seconds).count() << "ms\n";
    50. std::cout << "test2(atomic/multi-thread) -> " << " total_2: " << total_2 << " elapsed time(s): " << std::chrono::duration_cast(elapsed_seconds).count() << "s\n";
    51. }
    52. std::atomic<uint64_t> total_3;
    53. void pred3(void)
    54. {
    55. uint64_t expect = 0;
    56. uint64_t desired = 0;
    57. for (uint64_t i = 0; i <= 100000000; i++) {
    58. do
    59. {
    60. expect = total_3.load();
    61. desired = expect + i;
    62. } while (!total_3.compare_exchange_weak(expect, desired, std::memory_order_release, std::memory_order_relaxed));
    63. //} while (!total_3.compare_exchange_strong(expect, desired, std::memory_order_release, std::memory_order_relaxed));
    64. }
    65. }
    66. void test3()
    67. {
    68. std::cout << "thread[" << std::this_thread::get_id() << "]-3 start...\n";
    69. auto start = std::chrono::steady_clock::now();
    70. std::thread t1(pred3);
    71. std::thread t2(pred3);
    72. t1.join();
    73. t2.join();
    74. auto end = std::chrono::steady_clock::now();
    75. std::chrono::duration<double> elapsed_seconds = end - start;
    76. std::cout << "test3(CAS/multi-thread) -> " << " total_3: " << total_3 << " elapsed time(ms): " << std::chrono::duration_cast(elapsed_seconds).count() << "ms\n";
    77. std::cout << "test3(CAS/multi-thread) -> " << " total_3: " << total_3 << " elapsed time(s): " << std::chrono::duration_cast(elapsed_seconds).count() << "s\n";
    78. }
    79. void tesxxx()
    80. {
    81. total_1 = 0;
    82. std::cout << "tesxxx[" << std::this_thread::get_id() << "]-x start...\n";
    83. auto start = std::chrono::steady_clock::now();
    84. pred1();
    85. auto end = std::chrono::steady_clock::now();
    86. std::chrono::duration<double> elapsed_seconds = end - start;
    87. std::cout << "tesxxx(non-multi-thread) -> " << " total_1: " << total_1 << " elapsed time(ms): " << std::chrono::duration_cast(elapsed_seconds).count() << "ms\n";
    88. std::cout << "tesxxx(non-multi-thread) -> " << " total_1: " << total_1 << " elapsed time(s): " << std::chrono::duration_cast(elapsed_seconds).count() << "s\n";
    89. }
    90. int main()
    91. {
    92. tesxxx();
    93. test1();
    94. test2();
    95. test3();
    96. }

    结果

    tesxxx[16840]-x start...
    tesxxx(non-multi-thread) ->  total_1: 5000000050000000 elapsed time(ms): 8231ms
    tesxxx(non-multi-thread) ->  total_1: 5000000050000000 elapsed time(s): 8s
    thread[16840]-1 start...
    test1(mutex/multi-thread) ->  total_1: 10000000100000000 elapsed time(ms): 17387ms
    test1(mutex/multi-thread) ->  total_1: 10000000100000000 elapsed time(s): 17s
    thread[16840]-2 start...
    test2(atomic/multi-thread) ->  total_2: 10000000100000000 elapsed time(ms): 31167ms
    test2(atomic/multi-thread) ->  total_2: 10000000100000000 elapsed time(s): 31s
    thread[16840]-3 start...
    test3(CAS/multi-thread) ->  total_3: 10000000100000000 elapsed time(ms): 42721ms
    test3(CAS/multi-thread) ->  total_3: 10000000100000000 elapsed time(s): 42s

  • 相关阅读:
    双连通与网络可靠性
    Spring源码解析—— IOC默认标签解析(下)
    E. Red-Black Pepper
    最强大脑(1)
    Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法
    数组常用的几种排序方式
    input text文本框自动保存
    flask-sqlalchemy库
    大型架构设计的演进之路
    一文搞定class的微观结构和指令
  • 原文地址:https://blog.csdn.net/OneOnce/article/details/126245918