From 112e113201a47dbca1c39d7684e25f01cfa89ac7 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Wed, 7 Aug 2024 21:28:05 +0100 Subject: [PATCH] Optimize `DoCrawl` Benchmark: ``` cmake -S. -Bbuild-reld -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING=ON cmake --build build-reld --target crawl_benchmark && build-reld/crawl_benchmark ``` Before: ``` ------------------------------------------------------ Benchmark Time CPU Iterations ------------------------------------------------------ BM_Crawl/1 3.53 ns 3.53 ns 198384032 BM_Crawl/4 54.3 ns 54.2 ns 12907171 BM_Crawl/16 733 ns 732 ns 955101 BM_Crawl/20 1142 ns 1141 ns 613766 ``` After: ``` ------------------------------------------------------ Benchmark Time CPU Iterations ------------------------------------------------------ BM_Crawl/1 1.36 ns 1.36 ns 453018506 BM_Crawl/4 5.59 ns 5.59 ns 124244505 BM_Crawl/16 102 ns 101 ns 6577269 BM_Crawl/20 147 ns 147 ns 4684004 ``` --- Source/crawl.cpp | 79 +++++++++++++--------------------------- test/crawl_benchmark.cpp | 2 +- 2 files changed, 27 insertions(+), 54 deletions(-) diff --git a/Source/crawl.cpp b/Source/crawl.cpp index fe561a05b..90010f77d 100644 --- a/Source/crawl.cpp +++ b/Source/crawl.cpp @@ -7,66 +7,39 @@ #include "engine/displacement.hpp" namespace devilution { -namespace { - -bool CrawlFlipsX(Displacement mirrored, tl::function_ref function) -{ - for (const Displacement displacement : { mirrored.flipX(), mirrored }) { - if (!function(displacement)) - return false; - } - return true; -} - -bool CrawlFlipsY(Displacement mirrored, tl::function_ref function) -{ - for (const Displacement displacement : { mirrored, mirrored.flipY() }) { - if (!function(displacement)) - return false; - } - return true; -} - -bool CrawlFlipsXY(Displacement mirrored, tl::function_ref function) -{ - for (const Displacement displacement : { mirrored.flipX(), mirrored, mirrored.flipXY(), mirrored.flipY() }) { - if (!function(displacement)) - return false; - } - return true; -} - -} // namespace bool DoCrawl(unsigned radius, tl::function_ref function) { - if (radius == 0) - return function(Displacement { 0, 0 }); - - if (!CrawlFlipsY({ 0, static_cast(radius) }, function)) - return false; - for (unsigned i = 1; i < radius; i++) { - if (!CrawlFlipsXY({ static_cast(i), static_cast(radius) }, function)) - return false; - } - if (radius > 1) { - if (!CrawlFlipsXY({ static_cast(radius) - 1, static_cast(radius) - 1 }, function)) - return false; - } - if (!CrawlFlipsX({ static_cast(radius), 0 }, function)) - return false; - for (unsigned i = 1; i < radius; i++) { - if (!CrawlFlipsXY({ static_cast(radius), static_cast(i) }, function)) - return false; - } - return true; + return DoCrawl(radius, radius, function); } bool DoCrawl(unsigned minRadius, unsigned maxRadius, tl::function_ref function) { - for (unsigned i = minRadius; i <= maxRadius; i++) { - if (!DoCrawl(i, function)) - return false; + for (int r = static_cast(minRadius); r <= static_cast(maxRadius); ++r) { + if (!function(Displacement { 0, r })) return false; + if (r == 0) continue; + if (!function(Displacement { 0, -r })) return false; + for (int x = 1; x < r; ++x) { + if (!function(Displacement { -x, r })) return false; + if (!function(Displacement { x, r })) return false; + if (!function(Displacement { -x, -r })) return false; + if (!function(Displacement { x, -r })) return false; + } + if (r > 1) { + const int d = r - 1; + if (!function(Displacement { -d, d })) return false; + if (!function(Displacement { d, d })) return false; + if (!function(Displacement { -d, -d })) return false; + if (!function(Displacement { d, -d })) return false; + } + if (!function(Displacement { -r, 0 })) return false; + if (!function(Displacement { r, 0 })) return false; + for (int y = 1; y < r; ++y) { + if (!function(Displacement { -r, y })) return false; + if (!function(Displacement { r, y })) return false; + if (!function(Displacement { -r, -y })) return false; + if (!function(Displacement { r, -y })) return false; + } } return true; } diff --git a/test/crawl_benchmark.cpp b/test/crawl_benchmark.cpp index 8c47136ad..a11595601 100644 --- a/test/crawl_benchmark.cpp +++ b/test/crawl_benchmark.cpp @@ -8,7 +8,7 @@ namespace { void BM_Crawl(benchmark::State &state) { - const int radius = state.range(0); + const int radius = static_cast(state.range(0)); for (auto _ : state) { int sum; Crawl(0, radius, [&sum](Displacement d) {