Add profiler warmup overhead tracking and tooltip display

This commit is contained in:
max
2026-08-05 14:04:21 +02:00
parent d9582aecdd
commit 6ad5aa3f2c
3 changed files with 27 additions and 2 deletions
+10 -1
View File
@@ -194,7 +194,16 @@ namespace Nerfed.Editor.Systems
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.Text($"{node.SelfMilliseconds():0.000}"); ImGui.Text($"{node.SelfMilliseconds():0.000}");
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.Text($"{node.AllocatedBytes}"); if (node.ProfilerSetupBytes > 0)
{
ImGui.Text($"{node.AllocatedBytes} !");
if (ImGui.IsItemHovered())
ImGui.SetTooltip($"{node.ProfilerSetupBytes} B is profiler warmup overhead");
}
else
{
ImGui.Text($"{node.AllocatedBytes}");
}
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.Text($"{node.SelfAllocatedBytes()}"); ImGui.Text($"{node.SelfAllocatedBytes()}");
+12 -1
View File
@@ -434,6 +434,7 @@ public static class Profiler
public int ManagedThreadId { get; private set; } public int ManagedThreadId { get; private set; }
public List<ScopeNode> Children { get; } = new List<ScopeNode>(); public List<ScopeNode> Children { get; } = new List<ScopeNode>();
public long AllocatedBytes { get; private set; } public long AllocatedBytes { get; private set; }
public long ProfilerSetupBytes { get; private set; }
internal ScopeNode Parent { get; private set; } internal ScopeNode Parent { get; private set; }
internal long ChildrenDurationTicks { get; private set; } internal long ChildrenDurationTicks { get; private set; }
internal long ChildrenAllocatedBytes { get; private set; } internal long ChildrenAllocatedBytes { get; private set; }
@@ -451,6 +452,7 @@ public static class Profiler
ChildrenDurationTicks = 0; ChildrenDurationTicks = 0;
ChildrenAllocatedBytes = 0; ChildrenAllocatedBytes = 0;
AllocatedBytes = 0; AllocatedBytes = 0;
ProfilerSetupBytes = 0;
Children.Clear(); Children.Clear();
allocatedBytesAtStart = GC.GetAllocatedBytesForCurrentThread(); allocatedBytesAtStart = GC.GetAllocatedBytesForCurrentThread();
} }
@@ -463,9 +465,11 @@ public static class Profiler
} }
EndTime = Stopwatch.GetTimestamp(); EndTime = Stopwatch.GetTimestamp();
AllocatedBytes = Math.Max(0, GC.GetAllocatedBytesForCurrentThread() - allocatedBytesAtStart);
if (Parent != null) if (Parent != null)
{ {
// Root nodes are ended from FinalizeCurrentFrame on the main thread, so their
// GC counter would be from the wrong thread. Only track alloc on non-root nodes.
AllocatedBytes = Math.Max(0, GC.GetAllocatedBytesForCurrentThread() - allocatedBytesAtStart);
Parent.ChildrenDurationTicks += Math.Max(0, EndTime - StartTime); Parent.ChildrenDurationTicks += Math.Max(0, EndTime - StartTime);
Parent.ChildrenAllocatedBytes += AllocatedBytes; Parent.ChildrenAllocatedBytes += AllocatedBytes;
} }
@@ -488,6 +492,12 @@ public static class Profiler
return Math.Max(0, AllocatedBytes - ChildrenAllocatedBytes); return Math.Max(0, AllocatedBytes - ChildrenAllocatedBytes);
} }
// Called after all profiler setup (Children.Add + scopes.Push) to measure overhead within this scope's window.
internal void NoteSetupOverhead()
{
ProfilerSetupBytes = Math.Max(0, GC.GetAllocatedBytesForCurrentThread() - allocatedBytesAtStart);
}
internal ScopeNode AddChild(string label, string category, ulong tagMask) internal ScopeNode AddChild(string label, string category, ulong tagMask)
{ {
ScopeNode child = RentNode(label, category, tagMask, ManagedThreadId, this); ScopeNode child = RentNode(label, category, tagMask, ManagedThreadId, this);
@@ -648,6 +658,7 @@ public static class Profiler
ScopeNode newScope = scopes.Peek().AddChild(label, category, tagMask); ScopeNode newScope = scopes.Peek().AddChild(label, category, tagMask);
scopes.Push(newScope); scopes.Push(newScope);
newScope.NoteSetupOverhead();
} }
[Conditional("PROFILING")] [Conditional("PROFILING")]
+5
View File
@@ -372,6 +372,11 @@ public static class ProfilerVisualizer
ImGui.Text($"Timeline Start: {hover.StartInTimelineMs:0.000} ms"); ImGui.Text($"Timeline Start: {hover.StartInTimelineMs:0.000} ms");
ImGui.Text($"Timeline End: {hover.EndInTimelineMs:0.000} ms"); ImGui.Text($"Timeline End: {hover.EndInTimelineMs:0.000} ms");
ImGui.Text($"Children: {hover.Node.Children.Count}"); ImGui.Text($"Children: {hover.Node.Children.Count}");
if (hover.Node.ProfilerSetupBytes > 0)
{
ImGui.Separator();
ImGui.TextColored(new Vector4(1f, 0.75f, 0f, 1f), $"\u26a0 {hover.Node.ProfilerSetupBytes} B of alloc is profiler warmup overhead");
}
ImGui.EndTooltip(); ImGui.EndTooltip();
} }