OctreePerformanceTests.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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 <AzCore/UnitTest/TestTypes.h>
  9. #include <AzCore/Name/NameDictionary.h>
  10. #include <AzFramework/Visibility/OctreeSystemComponent.h>
  11. #if defined(HAVE_BENCHMARK)
  12. #include <random>
  13. #include <benchmark/benchmark.h>
  14. namespace Benchmark
  15. {
  16. class BM_Octree
  17. : public benchmark::Fixture
  18. {
  19. void internalSetUp()
  20. {
  21. if (!AZ::NameDictionary::IsReady())
  22. {
  23. AZ::NameDictionary::Create();
  24. }
  25. m_octreeSystemComponent = new AzFramework::OctreeSystemComponent;
  26. m_visScene = m_octreeSystemComponent->CreateVisibilityScene(AZ::Name("OctreeBenchmarkVisibilityScene"));
  27. m_dataArray.resize(1000000);
  28. m_queryDataArray.resize(1000);
  29. const unsigned int seed = 1;
  30. std::mt19937_64 rng(seed);
  31. std::uniform_real_distribution<float> unif;
  32. std::generate(m_dataArray.begin(), m_dataArray.end(), [&unif, &rng]()
  33. {
  34. AzFramework::VisibilityEntry data;
  35. AZ::Vector3 aabbMin = AZ::Vector3(unif(rng), unif(rng), unif(rng)) * 8000.0f;
  36. AZ::Vector3 aabbMax = AZ::Vector3(unif(rng), unif(rng), unif(rng)).GetAbs() * 50.0f + aabbMin;
  37. data.m_internalNode = nullptr;
  38. data.m_internalNodeIndex = 0;
  39. data.m_boundingVolume = AZ::Aabb::CreateFromMinMax(aabbMin, aabbMax);
  40. data.m_userData = nullptr;
  41. data.m_typeFlags = AzFramework::VisibilityEntry::TYPE_None;
  42. return data;
  43. });
  44. std::generate(m_queryDataArray.begin(), m_queryDataArray.end(), [&unif, &rng]()
  45. {
  46. QueryData data;
  47. AZ::Vector3 aabbMin = AZ::Vector3(unif(rng), unif(rng), unif(rng)) * 8000.0f;
  48. AZ::Vector3 aabbMax = AZ::Vector3(unif(rng), unif(rng), unif(rng)).GetAbs() * 250.0f + aabbMin;
  49. AZ::Vector3 frustumCenter = AZ::Vector3(unif(rng), unif(rng), unif(rng)) * 8000.0f;
  50. AZ::Quaternion quaternion = AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3(unif(rng), unif(rng), unif(rng)).GetNormalized(), unif(rng));
  51. data.aabb = AZ::Aabb::CreateFromMinMax(aabbMin, aabbMax);
  52. data.sphere = AZ::Sphere(AZ::Vector3(unif(rng), unif(rng), unif(rng)) * 8000.0f, unif(rng) * 250.0f);
  53. data.frustum = AZ::Frustum(AZ::ViewFrustumAttributes(
  54. AZ::Transform::CreateFromQuaternionAndTranslation(quaternion, frustumCenter), 1.0f,
  55. 2.0f * atanf(0.5f), unif(rng) * 10.0f, unif(rng) * 1000.0f));
  56. return data;
  57. });
  58. }
  59. void internalTearDown()
  60. {
  61. m_octreeSystemComponent->DestroyVisibilityScene(m_visScene);
  62. delete m_octreeSystemComponent;
  63. AZ::NameDictionary::Destroy();
  64. m_dataArray.clear();
  65. m_dataArray.shrink_to_fit();
  66. m_queryDataArray.clear();
  67. m_queryDataArray.shrink_to_fit();
  68. }
  69. public:
  70. void SetUp(const benchmark::State&) override
  71. {
  72. internalSetUp();
  73. }
  74. void SetUp(benchmark::State&) override
  75. {
  76. internalSetUp();
  77. }
  78. void TearDown(const benchmark::State&) override
  79. {
  80. internalTearDown();
  81. }
  82. void TearDown(benchmark::State&) override
  83. {
  84. internalTearDown();
  85. }
  86. void InsertEntries(uint32_t entryCount)
  87. {
  88. for (uint32_t i = 0; i < entryCount; ++i)
  89. {
  90. m_visScene->InsertOrUpdateEntry(m_dataArray[i]);
  91. }
  92. }
  93. void RemoveEntries(uint32_t entryCount)
  94. {
  95. for (uint32_t i = 0; i < entryCount; ++i)
  96. {
  97. m_visScene->RemoveEntry(m_dataArray[i]);
  98. }
  99. }
  100. struct QueryData
  101. {
  102. AZ::Aabb aabb;
  103. AZ::Sphere sphere;
  104. AZ::Frustum frustum;
  105. };
  106. AZStd::vector<AzFramework::VisibilityEntry> m_dataArray;
  107. AZStd::vector<QueryData> m_queryDataArray;
  108. AzFramework::OctreeSystemComponent* m_octreeSystemComponent = nullptr;
  109. AzFramework::IVisibilityScene* m_visScene = nullptr;
  110. };
  111. BENCHMARK_F(BM_Octree, InsertDelete1000)(benchmark::State& state)
  112. {
  113. constexpr uint32_t EntryCount = 1000;
  114. for ([[maybe_unused]] auto _ : state)
  115. {
  116. InsertEntries(EntryCount);
  117. RemoveEntries(EntryCount);
  118. }
  119. }
  120. BENCHMARK_F(BM_Octree, InsertDelete10000)(benchmark::State& state)
  121. {
  122. constexpr uint32_t EntryCount = 10000;
  123. for ([[maybe_unused]] auto _ : state)
  124. {
  125. InsertEntries(EntryCount);
  126. RemoveEntries(EntryCount);
  127. }
  128. }
  129. BENCHMARK_F(BM_Octree, InsertDelete100000)(benchmark::State& state)
  130. {
  131. constexpr uint32_t EntryCount = 100000;
  132. for ([[maybe_unused]] auto _ : state)
  133. {
  134. InsertEntries(EntryCount);
  135. RemoveEntries(EntryCount);
  136. }
  137. }
  138. BENCHMARK_F(BM_Octree, InsertDelete1000000)(benchmark::State& state)
  139. {
  140. constexpr uint32_t EntryCount = 1000000;
  141. for ([[maybe_unused]] auto _ : state)
  142. {
  143. InsertEntries(EntryCount);
  144. RemoveEntries(EntryCount);
  145. }
  146. }
  147. BENCHMARK_F(BM_Octree, EnumerateAabb1000)(benchmark::State& state)
  148. {
  149. constexpr uint32_t EntryCount = 1000;
  150. InsertEntries(EntryCount);
  151. for ([[maybe_unused]] auto _ : state)
  152. {
  153. for (auto& queryData : m_queryDataArray)
  154. {
  155. m_visScene->Enumerate(queryData.aabb, [](const AzFramework::IVisibilityScene::NodeData&) {});
  156. }
  157. }
  158. RemoveEntries(EntryCount);
  159. }
  160. BENCHMARK_F(BM_Octree, EnumerateAabb10000)(benchmark::State& state)
  161. {
  162. constexpr uint32_t EntryCount = 10000;
  163. InsertEntries(EntryCount);
  164. for ([[maybe_unused]] auto _ : state)
  165. {
  166. for (auto& queryData : m_queryDataArray)
  167. {
  168. m_visScene->Enumerate(queryData.aabb, [](const AzFramework::IVisibilityScene::NodeData&) {});
  169. }
  170. }
  171. RemoveEntries(EntryCount);
  172. }
  173. BENCHMARK_F(BM_Octree, EnumerateAabb100000)(benchmark::State& state)
  174. {
  175. constexpr uint32_t EntryCount = 100000;
  176. InsertEntries(EntryCount);
  177. for ([[maybe_unused]] auto _ : state)
  178. {
  179. for (auto& queryData : m_queryDataArray)
  180. {
  181. m_visScene->Enumerate(queryData.aabb, [](const AzFramework::IVisibilityScene::NodeData&) {});
  182. }
  183. }
  184. RemoveEntries(EntryCount);
  185. }
  186. BENCHMARK_F(BM_Octree, EnumerateAabb1000000)(benchmark::State& state)
  187. {
  188. constexpr uint32_t EntryCount = 1000000;
  189. InsertEntries(EntryCount);
  190. for ([[maybe_unused]] auto _ : state)
  191. {
  192. for (auto& queryData : m_queryDataArray)
  193. {
  194. m_visScene->Enumerate(queryData.aabb, [](const AzFramework::IVisibilityScene::NodeData&) {});
  195. }
  196. }
  197. RemoveEntries(EntryCount);
  198. }
  199. BENCHMARK_F(BM_Octree, EnumerateSphere1000)(benchmark::State& state)
  200. {
  201. constexpr uint32_t EntryCount = 1000;
  202. InsertEntries(EntryCount);
  203. for ([[maybe_unused]] auto _ : state)
  204. {
  205. for (auto& queryData : m_queryDataArray)
  206. {
  207. m_visScene->Enumerate(queryData.sphere, [](const AzFramework::IVisibilityScene::NodeData&) {});
  208. }
  209. }
  210. RemoveEntries(EntryCount);
  211. }
  212. BENCHMARK_F(BM_Octree, EnumerateSphere10000)(benchmark::State& state)
  213. {
  214. constexpr uint32_t EntryCount = 10000;
  215. InsertEntries(EntryCount);
  216. for ([[maybe_unused]] auto _ : state)
  217. {
  218. for (auto& queryData : m_queryDataArray)
  219. {
  220. m_visScene->Enumerate(queryData.sphere, [](const AzFramework::IVisibilityScene::NodeData&) {});
  221. }
  222. }
  223. RemoveEntries(EntryCount);
  224. }
  225. BENCHMARK_F(BM_Octree, EnumerateSphere100000)(benchmark::State& state)
  226. {
  227. constexpr uint32_t EntryCount = 100000;
  228. InsertEntries(EntryCount);
  229. for ([[maybe_unused]] auto _ : state)
  230. {
  231. for (auto& queryData : m_queryDataArray)
  232. {
  233. m_visScene->Enumerate(queryData.sphere, [](const AzFramework::IVisibilityScene::NodeData&) {});
  234. }
  235. }
  236. RemoveEntries(EntryCount);
  237. }
  238. BENCHMARK_F(BM_Octree, EnumerateSphere1000000)(benchmark::State& state)
  239. {
  240. constexpr uint32_t EntryCount = 1000000;
  241. InsertEntries(EntryCount);
  242. for ([[maybe_unused]] auto _ : state)
  243. {
  244. for (auto& queryData : m_queryDataArray)
  245. {
  246. m_visScene->Enumerate(queryData.sphere, [](const AzFramework::IVisibilityScene::NodeData&) {});
  247. }
  248. }
  249. RemoveEntries(EntryCount);
  250. }
  251. BENCHMARK_F(BM_Octree, EnumerateFrustum1000)(benchmark::State& state)
  252. {
  253. constexpr uint32_t EntryCount = 1000;
  254. InsertEntries(EntryCount);
  255. for ([[maybe_unused]] auto _ : state)
  256. {
  257. for (auto& queryData : m_queryDataArray)
  258. {
  259. m_visScene->Enumerate(queryData.frustum, [](const AzFramework::IVisibilityScene::NodeData&) {});
  260. }
  261. }
  262. RemoveEntries(EntryCount);
  263. }
  264. BENCHMARK_F(BM_Octree, EnumerateFrustum10000)(benchmark::State& state)
  265. {
  266. constexpr uint32_t EntryCount = 10000;
  267. InsertEntries(EntryCount);
  268. for ([[maybe_unused]] auto _ : state)
  269. {
  270. for (auto& queryData : m_queryDataArray)
  271. {
  272. m_visScene->Enumerate(queryData.frustum, [](const AzFramework::IVisibilityScene::NodeData&) {});
  273. }
  274. }
  275. RemoveEntries(EntryCount);
  276. }
  277. BENCHMARK_F(BM_Octree, EnumerateFrustum100000)(benchmark::State& state)
  278. {
  279. constexpr uint32_t EntryCount = 100000;
  280. InsertEntries(EntryCount);
  281. for ([[maybe_unused]] auto _ : state)
  282. {
  283. for (auto& queryData : m_queryDataArray)
  284. {
  285. m_visScene->Enumerate(queryData.frustum, [](const AzFramework::IVisibilityScene::NodeData&) {});
  286. }
  287. }
  288. RemoveEntries(EntryCount);
  289. }
  290. BENCHMARK_F(BM_Octree, EnumerateFrustum1000000)(benchmark::State& state)
  291. {
  292. constexpr uint32_t EntryCount = 1000000;
  293. InsertEntries(EntryCount);
  294. for ([[maybe_unused]] auto _ : state)
  295. {
  296. for (auto& queryData : m_queryDataArray)
  297. {
  298. m_visScene->Enumerate(queryData.frustum, [](const AzFramework::IVisibilityScene::NodeData&) {});
  299. }
  300. }
  301. RemoveEntries(EntryCount);
  302. }
  303. }
  304. #endif