SurfaceTagWeights optimization (#7436)
* Add comparison operators to SurfaceTagWeight. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed AddSurfaceTagWeight to always combine weights. This simplifies the API a bit and defines the behavior if someone ever tries to add a duplicate tag. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added benchmarks for measuring the performance-critical APIs. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed SurfaceTagWeights to a fixed_vector. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Memory/PoolAllocator.h>
|
||||
#include <AzCore/Math/Random.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
#include <AzCore/std/containers/span.h>
|
||||
@@ -270,6 +271,88 @@ namespace UnitTest
|
||||
->Arg( 2048 )
|
||||
->Unit(::benchmark::kMillisecond);
|
||||
|
||||
BENCHMARK_DEFINE_F(SurfaceDataBenchmark, BM_AddSurfaceTagWeight)(benchmark::State& state)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(Entity);
|
||||
|
||||
AZ::Crc32 tags[SurfaceData::SurfaceTagWeights::MaxSurfaceWeights];
|
||||
AZ::SimpleLcgRandom randomGenerator(1234567);
|
||||
|
||||
// Declare this outside the loop so that we aren't benchmarking creation and destruction.
|
||||
SurfaceData::SurfaceTagWeights weights;
|
||||
|
||||
bool clearEachTime = state.range(0) > 0;
|
||||
|
||||
// Create a list of randomly-generated tag values.
|
||||
for (auto& tag : tags)
|
||||
{
|
||||
tag = randomGenerator.GetRandom();
|
||||
}
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
// We'll benchmark this two ways:
|
||||
// 1. We clear each time, which means each AddSurfaceWeightIfGreater call will search the whole list then add.
|
||||
// 2. We don't clear, which means that after the first run, AddSurfaceWeightIfGreater will always try to replace values.
|
||||
if (clearEachTime)
|
||||
{
|
||||
weights.Clear();
|
||||
}
|
||||
|
||||
// For each tag, try to add it with a random weight.
|
||||
for (auto& tag : tags)
|
||||
{
|
||||
weights.AddSurfaceTagWeight(tag, randomGenerator.GetRandomFloat());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(SurfaceDataBenchmark, BM_AddSurfaceTagWeight)
|
||||
->Arg(false)
|
||||
->Arg(true)
|
||||
->ArgName("ClearEachTime");
|
||||
|
||||
BENCHMARK_DEFINE_F(SurfaceDataBenchmark, BM_HasAnyMatchingTags_NoMatches)(benchmark::State& state)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(Entity);
|
||||
|
||||
AZ::Crc32 tags[SurfaceData::SurfaceTagWeights::MaxSurfaceWeights];
|
||||
AZ::SimpleLcgRandom randomGenerator(1234567);
|
||||
|
||||
// Declare this outside the loop so that we aren't benchmarking creation and destruction.
|
||||
SurfaceData::SurfaceTagWeights weights;
|
||||
|
||||
// Create a list of randomly-generated tag values.
|
||||
for (auto& tag : tags)
|
||||
{
|
||||
// Specifically always set the last bit so that we can create comparison tags that won't match.
|
||||
tag = randomGenerator.GetRandom() | 0x01;
|
||||
|
||||
// Add the tag to our weights list with a random weight.
|
||||
weights.AddSurfaceTagWeight(tag, randomGenerator.GetRandomFloat());
|
||||
}
|
||||
|
||||
// Create a set of similar comparison tags that won't match. We still want a random distribution of values though,
|
||||
// because the SurfaceTagWeights might behave differently with ordered lists.
|
||||
SurfaceData::SurfaceTagVector comparisonTags;
|
||||
for (auto& tag : tags)
|
||||
{
|
||||
comparisonTags.emplace_back(tag ^ 0x01);
|
||||
}
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
// Test to see if any of our tags match.
|
||||
// All of comparison tags should get compared against all of the added tags.
|
||||
bool result = weights.HasAnyMatchingTags(comparisonTags);
|
||||
benchmark::DoNotOptimize(result);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(SurfaceDataBenchmark, BM_HasAnyMatchingTags_NoMatches);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user