StatisticalProfilerBenchmarks.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Tests/StatisticalProfilerHelpers.h>
  9. #if defined(HAVE_BENCHMARK)
  10. #include <benchmark/benchmark.h>
  11. namespace Benchmark
  12. {
  13. #define REGISTER_STATS_PROFILER_SINGLETHREADED_BENCHMARK(_fixture, _function) \
  14. BENCHMARK_REGISTER_F(_fixture, _function) \
  15. ->Iterations(UnitTest::LargeIterationCount);
  16. #define REGISTER_STATS_PROFILER_MULTITHREADED_BENCHMARK(_fixture, _function) \
  17. BENCHMARK_REGISTER_F(_fixture, _function) \
  18. ->ThreadRange(1, AZStd::thread::hardware_concurrency()) \
  19. ->Iterations(UnitTest::LargeIterationCount);
  20. // -- AZ::Statistics::StatisticalProfiler benchmarks --
  21. template<class StatIdType = AZStd::string, class MutexType = AZ::NullMutex>
  22. class StatisticalProfilerBenchmark
  23. : public UnitTest::AllocatorsBenchmarkFixture
  24. {
  25. using ProfilerType = AZ::Statistics::StatisticalProfiler<StatIdType, MutexType>;
  26. using TimedScopeType = typename ProfilerType::TimedScope;
  27. public:
  28. void RunBenchmark(benchmark::State& state)
  29. {
  30. if (state.thread_index() == 0)
  31. {
  32. m_profiler = new ProfilerType;
  33. for (int i = 0; i < state.threads(); ++i)
  34. {
  35. const AZStd::string threadStatName = AZStd::string::format("thread%03d", i);
  36. const auto threadStatId = UnitTest::ConvertNameToStatId<StatIdType>(threadStatName);
  37. m_profiler->GetStatsManager().AddStatistic(threadStatId, threadStatName, "us");
  38. }
  39. }
  40. const AZStd::string statName = AZStd::string::format("thread%03d", state.thread_index());
  41. const auto statId = UnitTest::ConvertNameToStatId<StatIdType>(statName);
  42. for ([[maybe_unused]] auto _ : state)
  43. {
  44. TimedScopeType timedScope(*m_profiler, statId);
  45. benchmark::DoNotOptimize(m_profiler);
  46. }
  47. if (state.thread_index() == 0)
  48. {
  49. delete m_profiler;
  50. }
  51. }
  52. protected:
  53. ProfilerType* m_profiler;
  54. };
  55. BENCHMARK_TEMPLATE_DEFINE_F(StatisticalProfilerBenchmark, String_SingleThreadedPerf)(benchmark::State& state)
  56. {
  57. RunBenchmark(state);
  58. }
  59. BENCHMARK_TEMPLATE_DEFINE_F(StatisticalProfilerBenchmark, HashValue32_SingleThreadedPerf, AZ::HashValue32)(benchmark::State& state)
  60. {
  61. RunBenchmark(state);
  62. }
  63. REGISTER_STATS_PROFILER_SINGLETHREADED_BENCHMARK(StatisticalProfilerBenchmark, String_SingleThreadedPerf)
  64. REGISTER_STATS_PROFILER_SINGLETHREADED_BENCHMARK(StatisticalProfilerBenchmark, HashValue32_SingleThreadedPerf)
  65. BENCHMARK_TEMPLATE_DEFINE_F(StatisticalProfilerBenchmark, String_Mutex_ThreadedPerf, AZStd::string, AZStd::mutex)(benchmark::State& state)
  66. {
  67. RunBenchmark(state);
  68. }
  69. BENCHMARK_TEMPLATE_DEFINE_F(StatisticalProfilerBenchmark, HashValue32_Mutex_ThreadedPerf, AZ::HashValue32, AZStd::mutex)(benchmark::State& state)
  70. {
  71. RunBenchmark(state);
  72. }
  73. REGISTER_STATS_PROFILER_MULTITHREADED_BENCHMARK(StatisticalProfilerBenchmark, String_Mutex_ThreadedPerf)
  74. REGISTER_STATS_PROFILER_MULTITHREADED_BENCHMARK(StatisticalProfilerBenchmark, HashValue32_Mutex_ThreadedPerf)
  75. BENCHMARK_TEMPLATE_DEFINE_F(StatisticalProfilerBenchmark, String_SpinMutex_ThreadedPerf, AZStd::string, AZStd::spin_mutex)(benchmark::State& state)
  76. {
  77. RunBenchmark(state);
  78. }
  79. BENCHMARK_TEMPLATE_DEFINE_F(StatisticalProfilerBenchmark, HashValue32_SpinMutex_ThreadedPerf, AZ::HashValue32, AZStd::spin_mutex)(benchmark::State& state)
  80. {
  81. RunBenchmark(state);
  82. }
  83. REGISTER_STATS_PROFILER_MULTITHREADED_BENCHMARK(StatisticalProfilerBenchmark, String_SpinMutex_ThreadedPerf)
  84. REGISTER_STATS_PROFILER_MULTITHREADED_BENCHMARK(StatisticalProfilerBenchmark, HashValue32_SpinMutex_ThreadedPerf)
  85. BENCHMARK_TEMPLATE_DEFINE_F(StatisticalProfilerBenchmark, String_SharedMutex_ThreadedPerf, AZStd::string, AZStd::shared_mutex)(benchmark::State& state)
  86. {
  87. RunBenchmark(state);
  88. }
  89. BENCHMARK_TEMPLATE_DEFINE_F(StatisticalProfilerBenchmark, HashValue32_SharedMutex_ThreadedPerf, AZ::HashValue32, AZStd::shared_mutex)(benchmark::State& state)
  90. {
  91. RunBenchmark(state);
  92. }
  93. REGISTER_STATS_PROFILER_MULTITHREADED_BENCHMARK(StatisticalProfilerBenchmark, String_SharedMutex_ThreadedPerf)
  94. REGISTER_STATS_PROFILER_MULTITHREADED_BENCHMARK(StatisticalProfilerBenchmark, HashValue32_SharedMutex_ThreadedPerf)
  95. // -- AZ::Statistics::StatisticalProfilerProxy benchmarks --
  96. class StatisticalProfilerProxyBenchmark
  97. : public UnitTest::AllocatorsBenchmarkFixture
  98. {
  99. using ProxyType = AZ::Statistics::StatisticalProfilerProxy;
  100. using ProfilerType = ProxyType::StatisticalProfilerType;
  101. using StatIdType = ProxyType::StatIdType;
  102. using TimedScopeType = ProxyType::TimedScope;
  103. public:
  104. void RunBenchmark(benchmark::State& state)
  105. {
  106. if (state.thread_index() == 0)
  107. {
  108. TimedScopeType::ClearCachedProxy();
  109. m_proxy = new ProxyType;
  110. ProfilerType& profiler = m_proxy->GetProfiler(UnitTest::ProfilerProxyGroup);
  111. for (int i = 0; i < state.threads(); ++i)
  112. {
  113. const AZStd::string threadStatName = AZStd::string::format("thread%03d", i);
  114. const auto threadStatId = UnitTest::ConvertNameToStatId<StatIdType>(threadStatName);
  115. profiler.GetStatsManager().AddStatistic(threadStatId, threadStatName, "us");
  116. }
  117. m_proxy->ActivateProfiler(UnitTest::ProfilerProxyGroup, true);
  118. }
  119. const AZStd::string statName = AZStd::string::format("thread%03d", state.thread_index());
  120. const auto statId = UnitTest::ConvertNameToStatId<StatIdType>(statName);
  121. for ([[maybe_unused]] auto _ : state)
  122. {
  123. TimedScopeType timedScope(UnitTest::ProfilerProxyGroup, statId);
  124. benchmark::DoNotOptimize(m_proxy);
  125. }
  126. if (state.thread_index() == 0)
  127. {
  128. delete m_proxy;
  129. }
  130. }
  131. protected:
  132. ProxyType* m_proxy;
  133. };
  134. BENCHMARK_DEFINE_F(StatisticalProfilerProxyBenchmark, GeneralPerf)(benchmark::State& state)
  135. {
  136. RunBenchmark(state);
  137. }
  138. REGISTER_STATS_PROFILER_MULTITHREADED_BENCHMARK(StatisticalProfilerProxyBenchmark, GeneralPerf)
  139. } // namespace Benchmark
  140. #endif // defined(HAVE_BENCHMARK)