mirror of
https://github.com/diasurgical/DevilutionX.git
synced 2026-11-07 09:26:09 -10:00
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 ```
This commit is contained in:
1 parent
bf98d9f533
commit
112e113201
2 files changed
+27
-54
No files matched your search
+26
-53
@@ -7,66 +7,39 @@
|
||||
#include "engine/displacement.hpp"
|
||||
|
||||
namespace devilution {
|
||||
namespace {
|
||||
|
||||
bool CrawlFlipsX(Displacement mirrored, tl::function_ref<bool(Displacement)> function)
|
||||
{
|
||||
for (const Displacement displacement : { mirrored.flipX(), mirrored }) {
|
||||
if (!function(displacement))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CrawlFlipsY(Displacement mirrored, tl::function_ref<bool(Displacement)> function)
|
||||
{
|
||||
for (const Displacement displacement : { mirrored, mirrored.flipY() }) {
|
||||
if (!function(displacement))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CrawlFlipsXY(Displacement mirrored, tl::function_ref<bool(Displacement)> 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<bool(Displacement)> function)
|
||||
{
|
||||
if (radius == 0)
|
||||
return function(Displacement { 0, 0 });
|
||||
|
||||
if (!CrawlFlipsY({ 0, static_cast<int>(radius) }, function))
|
||||
return false;
|
||||
for (unsigned i = 1; i < radius; i++) {
|
||||
if (!CrawlFlipsXY({ static_cast<int>(i), static_cast<int>(radius) }, function))
|
||||
return false;
|
||||
}
|
||||
if (radius > 1) {
|
||||
if (!CrawlFlipsXY({ static_cast<int>(radius) - 1, static_cast<int>(radius) - 1 }, function))
|
||||
return false;
|
||||
}
|
||||
if (!CrawlFlipsX({ static_cast<int>(radius), 0 }, function))
|
||||
return false;
|
||||
for (unsigned i = 1; i < radius; i++) {
|
||||
if (!CrawlFlipsXY({ static_cast<int>(radius), static_cast<int>(i) }, function))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return DoCrawl(radius, radius, function);
|
||||
}
|
||||
|
||||
bool DoCrawl(unsigned minRadius, unsigned maxRadius, tl::function_ref<bool(Displacement)> function)
|
||||
{
|
||||
for (unsigned i = minRadius; i <= maxRadius; i++) {
|
||||
if (!DoCrawl(i, function))
|
||||
return false;
|
||||
for (int r = static_cast<int>(minRadius); r <= static_cast<int>(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;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace {
|
||||
|
||||
void BM_Crawl(benchmark::State &state)
|
||||
{
|
||||
const int radius = state.range(0);
|
||||
const int radius = static_cast<int>(state.range(0));
|
||||
for (auto _ : state) {
|
||||
int sum;
|
||||
Crawl(0, radius, [&sum](Displacement d) {
|
||||
|
||||
Reference in new issue
Block a user