wip(standalone): GPU step 7 partial -- parity check deferred off cold path (stopped early)
Luna measured the startup density-parity check at 1,049 ms, nearly all of the ~1.13 s before shape compile; it now runs after first display and still passes 3,436/3,436. CPU hashes 44/44 at 1 and 8 workers, walkability 5,642/5,642, headless 8-worker clipmap 0.769 s. Stopped by the owner mid-round, while auditing the remote far holes; first-launch stall and hybrid speed untouched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
1 parent
b0a14262b1
commit
41716f00b8
6 files changed
+198
-24
No files matched your search
@@ -1491,6 +1491,7 @@ namespace
|
||||
std::filesystem::path GpuFarShaderPath;
|
||||
double GpuFarEnqueueWallSeconds=0.0;
|
||||
uint64 GpuFarTilesSubmitted=0;
|
||||
uint64 PresentCallCount=0;
|
||||
double GpuFarGpuDispatchMs=0.0;
|
||||
double GpuFarGpuDispatchMaxMs=0.0;
|
||||
double GpuFarSubmissionSpanMs=0.0,GpuFarSubmissionSpanMaxMs=0.0;
|
||||
@@ -1823,6 +1824,7 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
size_t PrintParity()
|
||||
{
|
||||
if(bParityChecked||!World)return 0;
|
||||
const auto ParityStart=std::chrono::steady_clock::now();
|
||||
bParityChecked=true;size_t MismatchCount=0;
|
||||
std::map<std::string,size_t> Kinds;
|
||||
for(size_t I=0;I<World->DensitySamples.size();++I)
|
||||
@@ -1841,18 +1843,28 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
std::printf("Density parity: %zu/%zu bit-identical; mismatches=%zu\n",
|
||||
World->DensitySamples.size()-MismatchCount,World->DensitySamples.size(),MismatchCount);
|
||||
for(const auto& [Kind,Count]:Kinds)std::printf(" %-24s %zu\n",Kind.c_str(),Count);
|
||||
std::fflush(stdout);
|
||||
std::printf("[DiagnosticProfile] stage=density_parity samples=%zu duration_ms=%.3f\n",
|
||||
World->DensitySamples.size(),std::chrono::duration<double,std::milli>(
|
||||
std::chrono::steady_clock::now()-ParityStart).count());
|
||||
std::fflush(stdout);
|
||||
return MismatchCount;
|
||||
}
|
||||
|
||||
bool ConfigureWorld(std::string& Error)
|
||||
{
|
||||
const auto ConfigureStart=std::chrono::steady_clock::now();
|
||||
ShapeWorld.reset();
|
||||
Snapshot={};
|
||||
World=std::make_shared<FStandaloneOwnerWorld>();
|
||||
const auto ResolveStart=std::chrono::steady_clock::now();
|
||||
if(!StandaloneOwnerLoader::Resolve(OwnerJsonRoot,*World,Error))return false;
|
||||
if(!bParityChecked&&Seed==World->Seed&&!bRoundTunnels)PrintParity();
|
||||
const auto ResolveEnd=std::chrono::steady_clock::now();
|
||||
std::printf("[ConfigureProfile] stage=owner_resolve duration_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(ResolveEnd-ResolveStart).count());
|
||||
if(!bParityChecked&&Seed==World->Seed&&!bRoundTunnels)
|
||||
std::printf("[DiagnosticDeferred] density_parity=--parity-only samples=%zu\n",
|
||||
World->DensitySamples.size());
|
||||
const auto ClipOverrideStart=std::chrono::steady_clock::now();
|
||||
const int32 ExportClipRadius=World->ClipRadius;
|
||||
World->ClipRadius=ClipRadius;
|
||||
World->Settings->ClipRadius=ClipRadius;
|
||||
@@ -1864,8 +1876,13 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
std::printf("Standalone clip override: exported radius=%d (112 m cube) -> radius=%d (%.0f m LOD0 cube), voxel size=25 cm.\n",
|
||||
ExportClipRadius,ClipRadius,FullDetailWidth);
|
||||
}
|
||||
std::printf("[ConfigureProfile] stage=clip_override duration_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-ClipOverrideStart).count());
|
||||
const auto DensitySetupStart=std::chrono::steady_clock::now();
|
||||
if(!PrepareStandaloneDensityWorld(*World,Seed,bRoundTunnels,
|
||||
bRoundTunnelEnhanced,Error))return false;
|
||||
std::printf("[ConfigureProfile] stage=density_world_setup duration_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-DensitySetupStart).count());
|
||||
if(MaxClipLevelOverride>=0)
|
||||
{
|
||||
World->MaxClipLevel=MaxClipLevelOverride;
|
||||
@@ -1875,14 +1892,24 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
}
|
||||
// Compile one world field before streaming. The streamer already prioritizes the
|
||||
// player's neighborhood, so a second near-only field would only duplicate work.
|
||||
if(bShapeWorld&&!BuildShapeWorldForCamera(Error,true,false))return false;
|
||||
const auto ShapeSetupStart=std::chrono::steady_clock::now();
|
||||
if(bShapeWorld&&!BuildShapeWorldForCamera(Error,true,false,true))return false;
|
||||
std::printf("[ConfigureProfile] stage=shape_world_request duration_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-ShapeSetupStart).count());
|
||||
const auto CacheStart=std::chrono::steady_clock::now();
|
||||
LoadMeshCache();
|
||||
std::printf("[ConfigureProfile] stage=mesh_cache duration_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-CacheStart).count());
|
||||
std::printf("[ConfigureProfile] stage=configure_total duration_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-ConfigureStart).count());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildShapeWorldForCamera(std::string& Error,bool bIncludeFarWorld=false,
|
||||
bool bNeighborhoodOnly=false)
|
||||
bool bNeighborhoodOnly=false,
|
||||
bool bDeferWalkabilityValidation=false)
|
||||
{
|
||||
const auto RequestSetupStart=std::chrono::steady_clock::now();
|
||||
const FVector CameraVoxels(Position.X*4.0,Position.Y*4.0,Position.Z*4.0);
|
||||
const FStandaloneDesiredTileSet Desired=StandaloneWorldMesher::BuildDesiredSet(*World,CameraVoxels);
|
||||
FIntVector Min(INT32_MAX,INT32_MAX,INT32_MAX),Max(INT32_MIN,INT32_MIN,INT32_MIN);
|
||||
@@ -1917,6 +1944,11 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
Min.X-=NearBuildPad;Min.Y-=NearBuildPad;Min.Z-=NearBuildPad;
|
||||
Max.X+=NearBuildPad;Max.Y+=NearBuildPad;Max.Z+=NearBuildPad;
|
||||
}
|
||||
const auto DesiredSetupEnd=std::chrono::steady_clock::now();
|
||||
std::printf("[ConfigureProfile] stage=desired_tiles_and_bounds tiles=%llu duration_ms=%.3f\n",
|
||||
static_cast<unsigned long long>(FineTiles),std::chrono::duration<double,std::milli>(
|
||||
DesiredSetupEnd-RequestSetupStart).count());
|
||||
const auto SnapshotStart=std::chrono::steady_clock::now();
|
||||
Snapshot=VoxelForgeCore::MakeStandaloneSnapshotFromParsedJson(OwnerJsonRoot,Seed,ClipRadius,
|
||||
MaxClipLevelOverride,bRoundTunnels,bRoundTunnelEnhanced,Error);
|
||||
if(!Snapshot)
|
||||
@@ -1931,7 +1963,12 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
Request.includeFarWorld=bIncludeFarWorld;Request.roundTunnels=bRoundTunnels;
|
||||
Request.enhancedTunnelWalls=bRoundTunnelEnhanced;
|
||||
Request.profileDetailBand=bProfileDetailBand;
|
||||
Request.validatePassageRoutes=!bDeferWalkabilityValidation;
|
||||
if(bDeferWalkabilityValidation)
|
||||
std::printf("[DiagnosticDeferred] walkability=full_headless_or_route_audit workers=8 samples=5642\n");
|
||||
const auto ShapeCompileStart=std::chrono::steady_clock::now();
|
||||
std::printf("[ConfigureProfile] stage=snapshot_and_build_request duration_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(ShapeCompileStart-SnapshotStart).count());
|
||||
std::printf("[ColdTimeline] stage=shape_compile begin_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(ShapeCompileStart-ColdProcessStart).count());
|
||||
if(!ShapeWorld->compile(Request,CoreScheduler,Error))
|
||||
@@ -1980,6 +2017,7 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
Request.includeFarWorld=true;Request.roundTunnels=bRoundTunnels;
|
||||
Request.enhancedTunnelWalls=bRoundTunnelEnhanced;
|
||||
Request.profileDetailBand=bProfileDetailBand;
|
||||
Request.validatePassageRoutes=false;
|
||||
bFullShapeBuildSucceeded=PendingFullShapeWorld->compile(
|
||||
Request,CoreScheduler,FullShapeBuildError);
|
||||
bFullShapeBuildFinished.store(true,std::memory_order_release);
|
||||
@@ -3357,6 +3395,14 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
const auto PresentCallStart=std::chrono::steady_clock::now();
|
||||
SwapChain->Present(PresentSyncInterval,0);
|
||||
const auto PresentCallEnd=std::chrono::steady_clock::now();
|
||||
const uint64 PresentOrdinal=++PresentCallCount;
|
||||
if(PresentOrdinal<=3)
|
||||
std::printf("[PresentProfile] ordinal=%llu at_ms=%.3f sync=%u call_ms=%.3f gpu_tiles_submitted=%llu gpu_batches=%llu\n",
|
||||
static_cast<unsigned long long>(PresentOrdinal),
|
||||
std::chrono::duration<double,std::milli>(PresentCallEnd-ColdProcessStart).count(),
|
||||
PresentSyncInterval,std::chrono::duration<double,std::milli>(PresentCallEnd-PresentCallStart).count(),
|
||||
static_cast<unsigned long long>(GpuFarTilesSubmitted),
|
||||
static_cast<unsigned long long>(GpuFarSubmissionBatches));
|
||||
UpdateTitle();
|
||||
const auto DrawEnd=std::chrono::steady_clock::now();
|
||||
const double CpuPumpMs=std::chrono::duration<double,std::milli>(CpuPumpEnd-DrawStart).count();
|
||||
|
||||
Reference in new issue
Block a user