wip(standalone): GPU step 11 -- per-shader cold cost measured; far EmitCS split, still CPU wins
Cold first-use per shader (queue ms): EvaluateFarField 1757, EmitNear 2429, FarConnectorRings 784, FarSkirts 507+975; the far EmitCS dropped 2327 -> 3.2 by splitting out the near midpoint fallback into EmitNearCS. Warm-up under 0xFF00 ~2.0 s (worker count and thread priority do not change it; 0xFFFF run: 1.71 s). Whole view median CPU 1.428 s vs hybrid 3.154 s. Audits unchanged. AMD DxCache was last written 2026-10-06 23:27 -- shaders may no longer be cached across launches (unverified). 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
10580650cb
commit
b6ac950073
19 files changed
+908
-24
No files matched your search
@@ -1490,6 +1490,9 @@ namespace
|
||||
bool bGpuFarAuditEnabled=false;
|
||||
bool bGpuFarShaderPrewarm=false,bDisableGpuWarmupPresentHold=false;
|
||||
bool bGpuFarWarmupResourcesOnly=false;
|
||||
bool bGpuFarWarmupNormalPriority=false,bGpuFarWarmupBeforeWorkers=false;
|
||||
bool bGpuFarWarmupOnly=false;
|
||||
std::string GpuWarmupEntryFilter;
|
||||
std::thread GpuShaderWarmupThread;
|
||||
bool bGpuShaderWarmupQueueSucceeded=false;
|
||||
std::string GpuShaderWarmupQueueError;
|
||||
@@ -1882,11 +1885,22 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
bGpuShaderWarmupQueueSucceeded=false;GpuShaderWarmupQueueError.clear();
|
||||
GpuShaderWarmupThread=std::thread([this]()
|
||||
{
|
||||
bool bNormalBasePriority=false;
|
||||
if(bGpuFarWarmupNormalPriority)
|
||||
{
|
||||
// The process stays BelowNormal; HIGHEST relative priority raises this
|
||||
// worker thread to a normal base priority on Windows.
|
||||
bNormalBasePriority=SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST)!=0;
|
||||
std::printf("[GpuShaderWarmupThread] priority=%s process=BelowNormal thread_relative=Highest\n",
|
||||
bNormalBasePriority?"Normal":"set_failed");
|
||||
std::fflush(stdout);
|
||||
}
|
||||
bGpuShaderWarmupQueueSucceeded=VoxelForgeGpuFarViewer::QueueFarShaderWarmup(
|
||||
Device,Context,GpuFarShaderPath,!bGpuFarWarmupResourcesOnly,
|
||||
Device,Context,GpuFarShaderPath,!bGpuFarWarmupResourcesOnly,GpuWarmupEntryFilter,
|
||||
GpuShaderWarmupQueueError);
|
||||
});
|
||||
std::printf("[GpuShaderWarmup] queue_thread=started overlap=CPU_shape_compile\n");
|
||||
std::printf("[GpuShaderWarmup] queue_thread=started overlap=%s\n",
|
||||
bGpuFarWarmupBeforeWorkers?"none_before_generation_workers":"CPU_shape_compile");
|
||||
std::fflush(stdout);
|
||||
}
|
||||
|
||||
@@ -5520,7 +5534,14 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
int main(int Argc,char** Argv)
|
||||
{
|
||||
SetPriorityClass(GetCurrentProcess(),BELOW_NORMAL_PRIORITY_CLASS);
|
||||
SetProcessAffinityMask(GetCurrentProcess(),static_cast<DWORD_PTR>(0xFF00));
|
||||
const bool bAllCpuAffinity=std::find_if(Argv+1,Argv+Argc,[](const char* Arg)
|
||||
{return std::string_view(Arg)=="--affinity-all-cpu";})!=Argv+Argc;
|
||||
const DWORD_PTR RequestedAffinity=static_cast<DWORD_PTR>(bAllCpuAffinity?0xFFFF:0xFF00);
|
||||
const BOOL bAffinitySet=SetProcessAffinityMask(GetCurrentProcess(),RequestedAffinity);
|
||||
DWORD_PTR ProcessAffinity=0,SystemAffinity=0;
|
||||
GetProcessAffinityMask(GetCurrentProcess(),&ProcessAffinity,&SystemAffinity);
|
||||
std::printf("[ProcessControls] priority_class=BelowNormal affinity_mask=0x%llX set=%s\n",
|
||||
static_cast<unsigned long long>(ProcessAffinity),bAffinitySet?"true":"false");
|
||||
const auto ColdProcessStart=std::chrono::steady_clock::now();
|
||||
FApp App;App.DataPath=DefaultDataPath().string();App.ColdProcessStart=ColdProcessStart;
|
||||
wchar_t ExecutablePath[MAX_PATH]{};
|
||||
@@ -5584,6 +5605,18 @@ int main(int Argc,char** Argv)
|
||||
App.bGpuFarEnabled=true,App.bGpuFarShaderPrewarm=true,App.bGpuFarWarmupResourcesOnly=true,
|
||||
App.bShapeWorld=true,App.bForceGenerate=true,App.bPresentCpuFrameBeforeGpu=true,
|
||||
App.bHoldCpuFrameDuringGpuWarmup=true;
|
||||
else if(Arg=="--gpu-far-warmup-normal-priority")
|
||||
App.bGpuFarWarmupNormalPriority=true;
|
||||
else if(Arg=="--gpu-far-warmup-before-workers")
|
||||
App.bGpuFarEnabled=true,App.bGpuFarShaderPrewarm=true,App.bGpuFarWarmupBeforeWorkers=true,
|
||||
App.bShapeWorld=true,App.bForceGenerate=true,App.bPresentCpuFrameBeforeGpu=true,
|
||||
App.bHoldCpuFrameDuringGpuWarmup=true;
|
||||
else if(Arg=="--gpu-far-warmup-only")
|
||||
App.bGpuFarEnabled=true,App.bGpuFarShaderPrewarm=true,App.bGpuFarWarmupOnly=true,
|
||||
App.bShapeWorld=true,App.bForceGenerate=true;
|
||||
else if(Arg.starts_with("--gpu-far-warmup-entry="))
|
||||
App.GpuWarmupEntryFilter=std::string(Arg.substr(std::string_view("--gpu-far-warmup-entry=").size()));
|
||||
else if(Arg=="--affinity-all-cpu"){}
|
||||
else if(Arg=="--gpu-far-no-present-hold")
|
||||
App.bDisableGpuWarmupPresentHold=true;
|
||||
else if(Arg=="--gpu-far-no-prewarm")
|
||||
@@ -5836,12 +5869,50 @@ int main(int Argc,char** Argv)
|
||||
std::printf("[ColdTimeline] stage=viewer_device_init end_ms=%.3f duration_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-ColdProcessStart).count(),
|
||||
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-DeviceInitStart).count());
|
||||
ShowWindow(App.Window,SW_SHOW);UpdateWindow(App.Window);
|
||||
std::printf("Controls: hold right mouse to look; WASD move; Space/Ctrl (E/Q) up/down; Shift faster; wheel changes speed; F wireframe; G toggles legacy/detailed round walls; H toggles CPU/GPU far tiles; 1-9 toggle LOD; 0 toggle all levels; N/P change seed; T swaps base/round tunnels; V swaps owner density/shape intervals; Esc quit.\n");
|
||||
std::printf("Owner data: %s; starting at first-strate open-space sample (%.2f, %.2f, %.2f) m.\n",
|
||||
App.DataPath.c_str(),App.Position.X,App.Position.Y,App.Position.Z);
|
||||
if(!App.bGpuFarWarmupOnly)
|
||||
{
|
||||
ShowWindow(App.Window,SW_SHOW);UpdateWindow(App.Window);
|
||||
std::printf("Controls: hold right mouse to look; WASD move; Space/Ctrl (E/Q) up/down; Shift faster; wheel changes speed; F wireframe; G toggles legacy/detailed round walls; H toggles CPU/GPU far tiles; 1-9 toggle LOD; 0 toggle all levels; N/P change seed; T swaps base/round tunnels; V swaps owner density/shape intervals; Esc quit.\n");
|
||||
std::printf("Owner data: %s; starting at first-strate open-space sample (%.2f, %.2f, %.2f) m.\n",
|
||||
App.DataPath.c_str(),App.Position.X,App.Position.Y,App.Position.Z);
|
||||
}
|
||||
std::fflush(stdout);
|
||||
if(App.bGpuFarWarmupOnly)
|
||||
{
|
||||
const auto WarmupOnlyStart=std::chrono::steady_clock::now();
|
||||
std::string WarmupError;
|
||||
if(!VoxelForgeGpuFarViewer::QueueFarShaderWarmup(App.Device,App.Context,App.GpuFarShaderPath,
|
||||
true,App.GpuWarmupEntryFilter,WarmupError))
|
||||
{std::fprintf(stderr,"[GpuShaderWarmupError] queue: %s\n",WarmupError.c_str());return 5;}
|
||||
if(!VoxelForgeGpuFarViewer::CompleteFarShaderWarmup(App.Device,App.Context,
|
||||
App.GpuFarShaderPath,WarmupError))
|
||||
{std::fprintf(stderr,"[GpuShaderWarmupError] completion: %s\n",WarmupError.c_str());return 5;}
|
||||
uint64 WarmupDxgiUsage=0,WarmupDxgiBudget=0;
|
||||
if(VoxelForgeGpuFarViewer::QueryFarGpuMemory(App.Device,App.Context,App.GpuFarShaderPath,
|
||||
WarmupDxgiUsage,WarmupDxgiBudget,WarmupError))
|
||||
std::printf("[GpuFarMemory] dxgi_local_sampled_peak_mb=%.3f budget_mb=%.3f\n",
|
||||
static_cast<double>(WarmupDxgiUsage)/1048576.0,
|
||||
static_cast<double>(WarmupDxgiBudget)/1048576.0);
|
||||
else
|
||||
std::printf("[GpuFarMemory] dxgi_local_sampled_peak_mb=unavailable reason=%s\n",
|
||||
WarmupError.c_str());
|
||||
std::printf("[GpuShaderWarmupOnlyComplete] entry=%s total_ms=%.3f\n",
|
||||
App.GpuWarmupEntryFilter.empty()?"all":App.GpuWarmupEntryFilter.c_str(),
|
||||
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-WarmupOnlyStart).count());
|
||||
return 0;
|
||||
}
|
||||
App.StartGpuShaderWarmupAsync();
|
||||
if(App.bGpuFarWarmupBeforeWorkers)
|
||||
{
|
||||
if(App.GpuShaderWarmupThread.joinable())App.GpuShaderWarmupThread.join();
|
||||
if(!App.bGpuShaderWarmupQueueSucceeded)
|
||||
{std::fprintf(stderr,"[GpuShaderWarmupError] queue: %s\n",App.GpuShaderWarmupQueueError.c_str());return 5;}
|
||||
std::string WarmupError;
|
||||
if(!VoxelForgeGpuFarViewer::CompleteFarShaderWarmup(App.Device,App.Context,
|
||||
App.GpuFarShaderPath,WarmupError))
|
||||
{std::fprintf(stderr,"[GpuShaderWarmupError] completion: %s\n",WarmupError.c_str());return 5;}
|
||||
std::printf("[GpuShaderWarmupBeforeWorkers] completed_before_generation_workers=true\n");
|
||||
}
|
||||
App.StartGeneration();
|
||||
MSG Message{};
|
||||
while(Message.message!=WM_QUIT)
|
||||
|
||||
Reference in new issue
Block a user