wip(standalone): GPU step 20 -- detail band batched by 8 columns; gap instrumented
ApplyDetailBand claims eight adjacent columns per batch, keeping each column's scalar order: shape stage ~586 -> ~566 ms in Luna's profile. Hashes w1/w8 identical. My runs outside the sandbox (Step20.exe, marker removed first, interleaved): CPU 1.319 / 1.287 / 1.288 s GPU 1.320 (marker miss, 0 GPU tiles) / 1.244 / 1.215 / 1.219 s (match, ~1,400 GPU) Shape compile 549-570 ms in both modes. The 669-821 ms gap in cached runs is still there: export starts only after [ChunkCrossingWork] reports the ~840 CPU tiles (LOD0-2) finished, so GPU export waits behind CPU meshing on the shared workers. Slowest GPU tile 1.7 / 18.4 / 27.3 ms in runs b/c/d. Audits: hashes, walk 5,642/5,642, near 960 / far 1,114 0 diffs vs CPU and WARP, thin 353, survival 6.14 GB, ten captures as step 18. Far vertex-distance diagnostic: 247 bound failures (max 64.56 cm), unchanged since step 16. 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
89fd9a0021
commit
2cb3344e1b
6 files changed
+146
-18
No files matched your search
@@ -1579,6 +1579,8 @@ namespace
|
||||
uint64 StartupNonBlockingPresentCalls=0,StartupNonBlockingPresentSkips=0;
|
||||
double GpuFarGpuDispatchMs=0.0;
|
||||
double GpuFarGpuDispatchMaxMs=0.0;
|
||||
FVoxelTileKey GpuFarGpuDispatchMaxKey{};
|
||||
bool bGpuFarGpuDispatchMaxKeyValid=false;
|
||||
double GpuFarSubmissionSpanMs=0.0,GpuFarSubmissionSpanMaxMs=0.0;
|
||||
uint64 GpuFarLocalMemoryPeakBytes=0,GpuFarLocalMemoryBudgetBytes=0;
|
||||
double GpuFarPoolReserveMs=0.0;
|
||||
@@ -1750,6 +1752,7 @@ namespace
|
||||
GpuFarAudit.reset();bGpuFarAuditReported=false;
|
||||
GpuFarTilesSubmitted=0;GpuFarEnqueueWallSeconds=0.0;GpuFarGpuDispatchMs=0.0;
|
||||
GpuFarGpuDispatchMaxMs=0.0;GpuFarSubmissionSpanMs=0.0;GpuFarSubmissionSpanMaxMs=0.0;
|
||||
GpuFarGpuDispatchMaxKey={};bGpuFarGpuDispatchMaxKeyValid=false;
|
||||
GpuFarLocalMemoryPeakBytes=0;GpuFarLocalMemoryBudgetBytes=0;
|
||||
bGpuFarFirstTileReported=false;
|
||||
GpuSkirtDrawAuditTiles=GpuSkirtDrawAuditZeroCounts=GpuSkirtDrawAuditOverflow=0;
|
||||
@@ -2743,7 +2746,11 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
{
|
||||
Tile.GpuDispatchMs=TileDispatchMs;Tile.bTimingResolved=true;
|
||||
GpuFarGpuDispatchMs+=TileDispatchMs;
|
||||
GpuFarGpuDispatchMaxMs=std::max(GpuFarGpuDispatchMaxMs,TileDispatchMs);
|
||||
if(TileDispatchMs>GpuFarGpuDispatchMaxMs)
|
||||
{
|
||||
GpuFarGpuDispatchMaxMs=TileDispatchMs;
|
||||
GpuFarGpuDispatchMaxKey=Key;bGpuFarGpuDispatchMaxKeyValid=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(Batch.bGpuComplete)
|
||||
@@ -2769,7 +2776,11 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
{
|
||||
Tile.GpuDispatchMs=AsyncDispatchMs;
|
||||
GpuFarGpuDispatchMs+=AsyncDispatchMs;
|
||||
GpuFarGpuDispatchMaxMs=std::max(GpuFarGpuDispatchMaxMs,AsyncDispatchMs);
|
||||
if(AsyncDispatchMs>GpuFarGpuDispatchMaxMs)
|
||||
{
|
||||
GpuFarGpuDispatchMaxMs=AsyncDispatchMs;
|
||||
GpuFarGpuDispatchMaxKey=Key;bGpuFarGpuDispatchMaxKeyValid=true;
|
||||
}
|
||||
}
|
||||
Tile.bTimingResolved=true;
|
||||
}
|
||||
@@ -2784,10 +2795,16 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
return ResidentTiles.contains(Key);
|
||||
}
|
||||
|
||||
void PrepareGpuFarInputs(std::vector<FVoxelTileKey> NeedPreparation)
|
||||
void PrepareGpuFarInputs(std::vector<FVoxelTileKey> NeedPreparation,
|
||||
std::chrono::steady_clock::time_point DispatchAt)
|
||||
{
|
||||
if(NeedPreparation.empty())return;
|
||||
const auto PrepareStart=std::chrono::steady_clock::now();
|
||||
if(bGpuFarTimelineEnabled)
|
||||
std::printf("[ColdTimeline] event=gpu_input_export_thread_started at_ms=%.3f dispatch_to_start_ms=%.3f frame=%llu\n",
|
||||
ColdTimelineMilliseconds(PrepareStart),
|
||||
std::chrono::duration<double,std::milli>(PrepareStart-DispatchAt).count(),
|
||||
static_cast<unsigned long long>(ColdTimelineFrame()));
|
||||
std::printf("[ColdTimeline] stage=gpu_input_export begin_ms=%.3f tiles=%zu\n",
|
||||
ColdTimelineMilliseconds(PrepareStart),NeedPreparation.size());
|
||||
const std::size_t ThreadCount=std::min<std::size_t>(8,NeedPreparation.size());
|
||||
@@ -3017,19 +3034,36 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
std::chrono::steady_clock::now()-ReserveStart).count();
|
||||
std::printf("[ColdTimeline] stage=gpu_output_pool end_ms=%.3f duration_ms=%.3f\n",
|
||||
ColdTimelineMilliseconds(std::chrono::steady_clock::now()),GpuFarPoolReserveMs);
|
||||
const auto PoolEnd=std::chrono::steady_clock::now();
|
||||
const auto MemorySampleStart=std::chrono::steady_clock::now();
|
||||
SampleGpuFarMemory();
|
||||
const double MemorySampleMs=std::chrono::duration<double,std::milli>(
|
||||
std::chrono::steady_clock::now()-MemorySampleStart).count();
|
||||
if(GpuFarNeedPreparation.empty())
|
||||
{
|
||||
bGpuFarPreparationFinished.store(true,std::memory_order_relaxed);
|
||||
return;
|
||||
}
|
||||
bGpuFarPreparationFinished.store(false,std::memory_order_relaxed);
|
||||
const auto PreparationListStart=std::chrono::steady_clock::now();
|
||||
std::vector<FVoxelTileKey> NeedPreparation=GpuFarNeedPreparation;
|
||||
std::stable_sort(NeedPreparation.begin(),NeedPreparation.end(),
|
||||
[&](const FVoxelTileKey& A,const FVoxelTileKey& B){return GpuFarKeyLess(A,B);});
|
||||
GpuFarPreparationThread=std::thread([this,NeedPreparation]()
|
||||
const double PreparationListMs=std::chrono::duration<double,std::milli>(
|
||||
std::chrono::steady_clock::now()-PreparationListStart).count();
|
||||
const auto DispatchAt=std::chrono::steady_clock::now();
|
||||
if(bGpuFarTimelineEnabled)
|
||||
std::printf("[ColdTimeline] event=gpu_input_export_thread_dispatch at_ms=%.3f after_pool_ms=%.3f memory_sample_ms=%.3f list_copy_sort_ms=%.3f tiles=%zu\n",
|
||||
ColdTimelineMilliseconds(DispatchAt),
|
||||
std::chrono::duration<double,std::milli>(DispatchAt-PoolEnd).count(),
|
||||
MemorySampleMs,PreparationListMs,NeedPreparation.size());
|
||||
GpuFarPreparationThread=std::thread([this,NeedPreparation,DispatchAt]()
|
||||
{
|
||||
try { PrepareGpuFarInputs(NeedPreparation); }
|
||||
const bool bPrioritySet=SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL)!=0;
|
||||
if(bGpuFarTimelineEnabled)
|
||||
std::printf("[GpuFarPreparationThread] priority=%s process=BelowNormal thread_relative=Normal\n",
|
||||
bPrioritySet?"Normal":"set_failed");
|
||||
try { PrepareGpuFarInputs(NeedPreparation,DispatchAt); }
|
||||
catch(const std::exception& Error)
|
||||
{
|
||||
std::lock_guard Lock(GpuFarPreparedResultsMutex);
|
||||
@@ -3784,7 +3818,11 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
if(GpuDispatchMs>0.0)
|
||||
{
|
||||
GpuFarGpuDispatchMs+=GpuDispatchMs;
|
||||
GpuFarGpuDispatchMaxMs=std::max(GpuFarGpuDispatchMaxMs,GpuDispatchMs);
|
||||
if(GpuDispatchMs>GpuFarGpuDispatchMaxMs)
|
||||
{
|
||||
GpuFarGpuDispatchMaxMs=GpuDispatchMs;
|
||||
GpuFarGpuDispatchMaxKey=Key;bGpuFarGpuDispatchMaxKeyValid=true;
|
||||
}
|
||||
Tile.bTimingResolved=true;
|
||||
}
|
||||
++GpuFarTilesSubmitted;++Built;
|
||||
@@ -4577,6 +4615,11 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
}
|
||||
const double AverageGpuMs=GpuFarTilesSubmitted
|
||||
?GpuFarGpuDispatchMs/static_cast<double>(GpuFarTilesSubmitted):0.0;
|
||||
if(bGpuFarGpuDispatchMaxKeyValid)
|
||||
std::printf("[GpuFarMaxDispatchTile] key=(%d,%d,%d,lod%d) dispatch_ms=%.6f\n",
|
||||
GpuFarGpuDispatchMaxKey.Coord.X,GpuFarGpuDispatchMaxKey.Coord.Y,
|
||||
GpuFarGpuDispatchMaxKey.Coord.Z,GpuFarGpuDispatchMaxKey.Level,
|
||||
GpuFarGpuDispatchMaxMs);
|
||||
std::printf("[GpuFarModeTiming] mode=%s cpu_mesh_tiles=%llu cpu_mesh_worker_sum_s=%.6f cpu_input_export_worker_sum_s=%.6f gpu_submitted_tiles=%llu gpu_busy_timestamp_sum_ms=%.3f whole_view_wall_s=%.6f warmup_cpu_claimed=%llu warmup_gpu_takeover=%llu\n",
|
||||
bGpuFarAuditEnabled?"gpu_audit":"gpu_hybrid",
|
||||
static_cast<unsigned long long>(CpuMeshTiles),CpuMeshWorkerSeconds,
|
||||
|
||||
Reference in new issue
Block a user