wip(standalone): GPU step 17 -- far skirt-depth fix (LOD3/4 back on GPU); adaptive start trades cached speed for first-launch
Coverage: the broad missing patch on far tiles was GPU skirt depth using the LOD key
step instead of the exported coarse mesher step (800 vs 1,600 cm at (6,2,0,lod3)).
Fixed; tile pixel-identical to CPU, 680/680 + 64/64 triangles, 1,434 GPU-eligible
tiles (was 1,082). Audits: hashes w1/w8, walk 5,642/5,642, thin/protected 0 diffs
vs CPU and WARP, survival 6.15 GB.
Adaptive start: CPU owns the first view while the shader queue is pending.
My runs outside the sandbox (Step17.exe, interleaved):
CPU 1.375 / 1.363 / 1.354 s
GPU 2.040 (first launch of build; 0 GPU tiles, CPU worker sum 6.98 vs 5.05 s)
/ 1.279 / 1.337 / 1.328 s
Cached warm-up queue now 329-632 ms (step 16: ~3 ms), so GPU took 258 tiles
once and 0 twice: cached GPU ~= CPU, a regression from step 16's 1.26 s.
First launch improved 3.09 -> 2.04 s but still loses to CPU. Also adds
STEP16_REPORT.md, missed in 666dfb8.
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
666dfb811c
commit
6f2d33e0a9
23 files changed
+1701
-104
No files matched your search
@@ -478,7 +478,7 @@ public:
|
||||
for(std::thread& Worker:Workers)if(Worker.joinable())Worker.join();
|
||||
Workers.clear();
|
||||
std::lock_guard<std::mutex> Lock(Mutex);
|
||||
Ready.clear();Outstanding.clear();Desired.clear();
|
||||
Ready.clear();Outstanding.clear();Desired.clear();Running.clear();
|
||||
}
|
||||
|
||||
FStandaloneStreamingUpdate UpdateDesired(
|
||||
@@ -512,6 +512,75 @@ public:
|
||||
return Out;
|
||||
}
|
||||
|
||||
FStandaloneStreamingUpdate RestrictDesiredTileFilterKeepingStarted(
|
||||
const std::vector<FVoxelTileKey>& BaseFilter,
|
||||
const std::vector<FVoxelTileKey>& CandidateKeys,
|
||||
const std::vector<FVoxelTileKey>& ResidentKeys,
|
||||
std::vector<FVoxelTileKey>& RetainedCandidateKeys)
|
||||
{
|
||||
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> Candidates;
|
||||
Candidates.reserve(CandidateKeys.size()*2+1);
|
||||
for(const FVoxelTileKey& Key:CandidateKeys)Candidates.insert(Key);
|
||||
|
||||
FStandaloneStreamingUpdate Stats;
|
||||
std::lock_guard<std::mutex> Lock(Mutex);
|
||||
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> Retained;
|
||||
Retained.reserve(CandidateKeys.size()*2+1);
|
||||
for(const FVoxelTileKey& Key:Running)
|
||||
if(Candidates.contains(Key))Retained.insert(Key);
|
||||
for(const FStandaloneCpuTile& Tile:Ready)
|
||||
if(Candidates.contains(Tile.Key))Retained.insert(Tile.Key);
|
||||
for(const FVoxelTileKey& Key:ResidentKeys)
|
||||
if(Candidates.contains(Key))Retained.insert(Key);
|
||||
|
||||
TileFilter.clear();
|
||||
TileFilter.reserve((BaseFilter.size()+Retained.size())*2+1);
|
||||
for(const FVoxelTileKey& Key:BaseFilter)TileFilter.insert(Key);
|
||||
for(const FVoxelTileKey& Key:Retained)TileFilter.insert(Key);
|
||||
bUseTileFilter=true;
|
||||
|
||||
FStandaloneDesiredTileSet NewDesired=CurrentDesired;
|
||||
NewDesired.Tiles.erase(std::remove_if(NewDesired.Tiles.begin(),NewDesired.Tiles.end(),
|
||||
[&](const FVoxelTileKey& Key){return !TileFilter.contains(Key);}),NewDesired.Tiles.end());
|
||||
Stats.CenterChunk=NewDesired.CenterChunk;
|
||||
Stats.DesiredTiles=static_cast<int32>(NewDesired.Tiles.size());
|
||||
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> ResidentSet;
|
||||
ResidentSet.reserve(ResidentKeys.size()*2+1);
|
||||
for(const FVoxelTileKey& Key:ResidentKeys)ResidentSet.insert(Key);
|
||||
for(const FVoxelTileKey& Key:NewDesired.Tiles)
|
||||
{
|
||||
if(Key.Level<World->FullResClipLevels)++Stats.FullResTiles;
|
||||
if(ResidentSet.contains(Key))++Stats.RetainedResidentTiles;
|
||||
}
|
||||
|
||||
Desired.clear();Desired.reserve(NewDesired.Tiles.size()*2+1);
|
||||
for(const FVoxelTileKey& Key:NewDesired.Tiles)Desired.insert(Key);
|
||||
FullResTileCount=Stats.FullResTiles;
|
||||
std::unordered_map<uint64,uint64> CancelledByCrossing;
|
||||
auto QueueEnd=std::remove_if(Queue.begin(),Queue.end(),[&](const FStandaloneTileJob& Job)
|
||||
{
|
||||
if(Desired.contains(Job.Key))return false;
|
||||
if(bColdTimelineTrace)TraceTileEvent("cancelled",Job.Key,FClock::now(),Job.QueuedAt);
|
||||
Outstanding.erase(Job.Key);++Stats.CancelledQueuedJobs;
|
||||
++CancelledByCrossing[Job.RequestedCrossing];return true;
|
||||
});
|
||||
Queue.erase(QueueEnd,Queue.end());
|
||||
std::make_heap(Queue.begin(),Queue.end(),FStandaloneTileJobHeapOrder{});
|
||||
Stats.CancelledByCrossing.reserve(CancelledByCrossing.size());
|
||||
for(const auto& Pair:CancelledByCrossing)Stats.CancelledByCrossing.push_back(Pair);
|
||||
CurrentDesired=std::move(NewDesired);
|
||||
RetainedCandidateKeys.assign(Retained.begin(),Retained.end());
|
||||
std::sort(RetainedCandidateKeys.begin(),RetainedCandidateKeys.end(),
|
||||
[](const FVoxelTileKey& A,const FVoxelTileKey& B)
|
||||
{
|
||||
if(A.Level!=B.Level)return A.Level<B.Level;
|
||||
if(A.Coord.Z!=B.Coord.Z)return A.Coord.Z<B.Coord.Z;
|
||||
if(A.Coord.Y!=B.Coord.Y)return A.Coord.Y<B.Coord.Y;
|
||||
return A.Coord.X<B.Coord.X;
|
||||
});
|
||||
return Stats;
|
||||
}
|
||||
|
||||
bool IsDesired(const FVoxelTileKey& Key)const
|
||||
{std::lock_guard<std::mutex> Lock(Mutex);return Desired.contains(Key);}
|
||||
int32 DesiredCount()const
|
||||
@@ -739,6 +808,7 @@ private:
|
||||
if(bStop)return;
|
||||
std::pop_heap(Queue.begin(),Queue.end(),FStandaloneTileJobHeapOrder{});
|
||||
Job=Queue.back();Queue.pop_back();Job.StartedAt=FClock::now();
|
||||
Running.insert(Job.Key);
|
||||
}
|
||||
if(bColdTimelineTrace)TraceTileEvent("started",Job.Key,Job.StartedAt,Job.QueuedAt,Job.StartedAt);
|
||||
FStandaloneCpuTile Tile=Generate(Job);
|
||||
@@ -747,6 +817,7 @@ private:
|
||||
{
|
||||
std::lock_guard<std::mutex> Lock(Mutex);
|
||||
if(bStop)return;
|
||||
Running.erase(Tile.Key);
|
||||
Ready.push_back(std::move(Tile));
|
||||
}
|
||||
}
|
||||
@@ -788,6 +859,7 @@ private:
|
||||
std::vector<std::thread> Workers;
|
||||
std::vector<FStandaloneTileJob> Queue;
|
||||
std::vector<FStandaloneCpuTile> Ready;
|
||||
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> Running;
|
||||
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> Desired;
|
||||
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> Outstanding;
|
||||
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> TileFilter;
|
||||
|
||||
Reference in new issue
Block a user