wip(step1): collision/upload clocks behind default-off switches -- partial, stopped on low memory

Compiled and run (cap 14 / 12 / 8), then stopped: another app held 12.5 GB, free memory fell
under the 6 GB launch floor and processes failed to start (STATUS_DLL_INIT_FAILED).

Measured so far (owner world, 120 s windows):
- 343 L0 tiles, request->collision-ready p50/p95: cap 14 = 262/440 ms, cap 8 = 196/238 ms;
  scheduler queue wait p95 141 ms -> 0.9 ms. Initial support tile at cap 14: RMC submit->body
  7.47 s, first check->ready 9.73 s; at cap 12: 0.33 s / 2.54 s; at cap 8 a 3,949-tri tile
  reached body update 2.8 ms after RMC submission. Waiting, not cooking, dominates.
- NOT confirmed: a capsule sweep hitting the exact target body (the 0.75 ms hit was another
  component); the 10 ms core-cook and 150 ms/27-tile thresholds are unscored.
- CMC cannot take a same-frame density floor: FindFloor/ComputeFloorDist trace the collision
  scene. Underfoot digs (100-dig test), upload throughput (render-enabled caps 4/8/16) and the
  8x per-sample question are not run. Per-sample profiling was fully disabled in these runs, so
  it does not explain the 8x.
Switches (all default off): voxel.Step1GenerationCap, Step1PauseGenerationAfterSeconds,
Step1MaxMeshApplies, Step1PrequeueVisibleLOD0, Step1UploadDisableCollision, Step1CollisionProbe,
Step1CoreCookBenchmark; harness -EnableRender. Also: plan step 3b, AVX2 need not match scalar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-09-29 17:53:57 +02:00
1 parent 6d2a068308
commit 97a1874498
5 files changed
+613 -19

No files matched your search

+28
View File
@@ -294,6 +294,8 @@ public:
bool bBodyUpdatedEventSeen = false;
uint64 BodyUpdatedEventCycles = 0;
uint64 BodyUpdatedEventFrame = 0;
bool bPhysicsStateReadyAtBodyUpdate = false;
uint64 PhysicsStateReadyCycles = 0;
uint64 FutureCallbackCycles = 0;
uint64 CompletionGameThreadCycles = 0;
// Game-thread-only timing copied from the generation result for the clean LOD0 summary.
@@ -320,6 +322,29 @@ public:
uint64 NextCollisionSubmissionId = 0;
TMap<URealtimeMesh*, FDelegateHandle> CollisionBodyUpdatedHandles;
struct FStep1SupportSweepProbe
{
uint64 CollisionRequestCycles = 0;
uint64 BodyUpdatedCycles = 0;
uint64 PhysicsStateReadyCycles = 0;
bool bFirstSweepAttemptLogged = false;
};
TMap<FVoxelTileKey, FStep1SupportSweepProbe> Step1SupportSweepProbes;
struct FStep1VisibleApplyProbe
{
uint64 AppliedCycles = 0;
uint64 AppliedFrame = 0;
float LastRenderTimeBeforeApply = 0.0f;
};
TMap<FVoxelTileKey, FStep1VisibleApplyProbe> Step1PendingVisibleApplyProbes;
TArray<FChunkResult> Step1HeldApplyResults;
TSet<FVoxelTileKey> Step1HeldApplyTiles;
int32 Step1HeldVisibleLOD0Count = 0;
int32 Step1LastLoggedPrequeueCount = -1;
int32 Step1HeldApplyCursor = 0;
bool bStep1UploadCorpusReleased = false;
/** Render component per NON-empty loaded tile (GC-safe via actor ownership; not UPROPERTY
* because FVoxelTileKey isn't a USTRUCT key). */
TMap<FVoxelTileKey, URealtimeMeshComponent*> TileComponents;
@@ -347,6 +372,7 @@ public:
* capped to (logical cores − 2) so small CPUs don't thrash on a flat 16 (background
* priority stops frame starvation, not the context-switch overhead). */
int32 GetMaxConcurrentTasks() const;
int32 GetActiveGenerationTaskCount() const;
/** Reserve task slots for collision-critical/edit/LOD0 work; far work uses the remainder. */
int32 GetNearTaskReserve(int32 MaxTasks) const;
@@ -920,6 +946,8 @@ public:
void BindRealtimeMeshCollisionEvent(URealtimeMesh* Mesh);
void UnbindRealtimeMeshCollisionEvent(URealtimeMesh* Mesh);
void HandleRealtimeMeshCollisionBodyUpdated(URealtimeMesh* Mesh, UBodySetup* BodySetup);
void PollStep1SupportSweepProbes();
void PollStep1VisibleApplyProbes();
void RecordLOD0ReadySample(uint64 RequestStartCycles, uint64 GenerationStartCycles,
uint64 GenerationEndCycles, uint64 ApplyStartCycles,
uint64 ReadyCycles, uint64 CollisionSubmittedCycles);