unreal: remove 121 ms per-frame overlap scoring and 162 ms world-lock wait; keep support tiles (L96)
- Per-frame passage-overlap scoring over outstanding tiles (added in L85) measured 121 ms for 407 LOD2 candidates; removed (deterministic desired/travel order kept). - Visibility reconciliation read-locked the Core world per candidate while the far-world build held the writer lock (162 ms scan, 123 ms lock wait); the immutable render distance is cached. Visibility now <= 0.17 ms. - Ready player-support collision tiles stay in the collision-desired set: fixes the L95 SW outlier (LOD0 (3,0,-47/-48/-50) re-admitted); 6 SW runs without re-admission. - AVoxelWorld::Tick during the arrival burst: FI p99 3.7-4.3 ms (max 6.0), SW p99 8.2-8.9 ms (max 11.2). FI still shows rare 40-60 ms world ticks outside our actor scope (engine tick group). - Near-set times kept: FI 2.06-2.12 s, SW median 1.30 s after first admission. World unchanged. Fast tier PASS; Linux UE host builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
5389abed2e
commit
94f9aa6790
7 files changed
+923
-67
No files matched your search
@@ -18172,11 +18172,60 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
TArray<double> SpawnTickMilliseconds;
|
||||
TArray<double> WalkTickMilliseconds;
|
||||
TArray<TPair<double, double>> TickSamples;
|
||||
double WorldTickStartedSeconds = 0.0;
|
||||
double WorldActorPhaseStartedSeconds = 0.0;
|
||||
double WorldPostActorStartedSeconds = 0.0;
|
||||
double WorldPreActorMilliseconds = 0.0;
|
||||
double WorldActorPhaseMilliseconds = 0.0;
|
||||
double WorldPostActorMilliseconds = 0.0;
|
||||
const FDelegateHandle WorldTickStartHandle = FWorldDelegates::OnWorldTickStart.AddLambda(
|
||||
[&](UWorld* World, ELevelTick, float)
|
||||
{
|
||||
if (World == TestWorld)
|
||||
{
|
||||
WorldTickStartedSeconds = FPlatformTime::Seconds();
|
||||
}
|
||||
});
|
||||
const FDelegateHandle WorldPreActorTickHandle = FWorldDelegates::OnWorldPreActorTick.AddLambda(
|
||||
[&](UWorld* World, ELevelTick, float)
|
||||
{
|
||||
if (World == TestWorld)
|
||||
{
|
||||
const double NowSeconds = FPlatformTime::Seconds();
|
||||
WorldPreActorMilliseconds =
|
||||
(NowSeconds - WorldTickStartedSeconds) * 1000.0;
|
||||
WorldActorPhaseStartedSeconds = NowSeconds;
|
||||
}
|
||||
});
|
||||
const FDelegateHandle WorldPostActorTickHandle = FWorldDelegates::OnWorldPostActorTick.AddLambda(
|
||||
[&](UWorld* World, ELevelTick, float)
|
||||
{
|
||||
if (World == TestWorld)
|
||||
{
|
||||
const double NowSeconds = FPlatformTime::Seconds();
|
||||
WorldActorPhaseMilliseconds =
|
||||
(NowSeconds - WorldActorPhaseStartedSeconds) * 1000.0;
|
||||
WorldPostActorStartedSeconds = NowSeconds;
|
||||
}
|
||||
});
|
||||
const FDelegateHandle WorldTickEndHandle = FWorldDelegates::OnWorldTickEnd.AddLambda(
|
||||
[&](UWorld* World, ELevelTick, float)
|
||||
{
|
||||
if (World == TestWorld)
|
||||
{
|
||||
WorldPostActorMilliseconds =
|
||||
(FPlatformTime::Seconds() - WorldPostActorStartedSeconds) * 1000.0;
|
||||
}
|
||||
});
|
||||
bool bInitialSetReady = false;
|
||||
double InitialSetReadySeconds = -1.0;
|
||||
while (FPlatformTime::Seconds() - ActorBeginSeconds < RunDurationSeconds)
|
||||
{
|
||||
const double TickStartSeconds = FPlatformTime::Seconds();
|
||||
const uint64 TickFrame = GFrameCounter;
|
||||
WorldPreActorMilliseconds = 0.0;
|
||||
WorldActorPhaseMilliseconds = 0.0;
|
||||
WorldPostActorMilliseconds = 0.0;
|
||||
TestWorld->Tick(LEVELTICK_All, 0.016f);
|
||||
const double TickMilliseconds =
|
||||
(FPlatformTime::Seconds() - TickStartSeconds) * 1000.0;
|
||||
@@ -18184,6 +18233,7 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
const double ElapsedSeconds = FPlatformTime::Seconds() - ActorBeginSeconds;
|
||||
TickSamples.Emplace(ElapsedSeconds, TickMilliseconds);
|
||||
|
||||
const double ReadinessCheckStartSeconds = FPlatformTime::Seconds();
|
||||
if (!bInitialSetReady && Actor->IsVoxelForgeCoreReady()
|
||||
&& Actor->bAllChunksLoaded && Actor->PendingTiles.IsEmpty()
|
||||
&& Actor->PendingCollisionCooks.IsEmpty() && Actor->PendingUnload.IsEmpty()
|
||||
@@ -18198,8 +18248,30 @@ bool RunCoreWorldActorIntegrationTest(const FExploreArguments& Arguments, FStrin
|
||||
Actor->LoadedTiles.Num(), Actor->CollisionDesiredTiles.Num(),
|
||||
Actor->CollisionReadyTiles.Num()));
|
||||
}
|
||||
const double ReadinessCheckMilliseconds =
|
||||
(FPlatformTime::Seconds() - ReadinessCheckStartSeconds) * 1000.0;
|
||||
const double SleepStartSeconds = FPlatformTime::Seconds();
|
||||
FPlatformProcess::Sleep(0.016f);
|
||||
const double SleepMilliseconds =
|
||||
(FPlatformTime::Seconds() - SleepStartSeconds) * 1000.0;
|
||||
VoxelForgeStartupTrace::RecordEvent(TEXT("commandlet_world_tick_frame"), FString::Printf(
|
||||
TEXT("\"frame\":%llu,\"world_tick_ms\":%s,"
|
||||
"\"world_pre_actor_ms\":%s,\"world_actor_phase_ms\":%s,"
|
||||
"\"world_post_actor_ms\":%s,"
|
||||
"\"readiness_check_ms\":%s,\"sleep_ms\":%s,\"loop_ms\":%s"),
|
||||
static_cast<unsigned long long>(TickFrame),
|
||||
*FString::SanitizeFloat(TickMilliseconds),
|
||||
*FString::SanitizeFloat(WorldPreActorMilliseconds),
|
||||
*FString::SanitizeFloat(WorldActorPhaseMilliseconds),
|
||||
*FString::SanitizeFloat(WorldPostActorMilliseconds),
|
||||
*FString::SanitizeFloat(ReadinessCheckMilliseconds),
|
||||
*FString::SanitizeFloat(SleepMilliseconds),
|
||||
*FString::SanitizeFloat((FPlatformTime::Seconds() - TickStartSeconds) * 1000.0)));
|
||||
}
|
||||
FWorldDelegates::OnWorldTickStart.Remove(WorldTickStartHandle);
|
||||
FWorldDelegates::OnWorldPreActorTick.Remove(WorldPreActorTickHandle);
|
||||
FWorldDelegates::OnWorldPostActorTick.Remove(WorldPostActorTickHandle);
|
||||
FWorldDelegates::OnWorldTickEnd.Remove(WorldTickEndHandle);
|
||||
|
||||
for (const TPair<double, double>& Sample : TickSamples)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user