Skip to content

Commit 0c3a45a

Browse files
committed
More detailed perf monitor
1 parent 9e8f23d commit 0c3a45a

2 files changed

Lines changed: 49 additions & 8 deletions

File tree

RLBotCS/ManagerTools/PerfMonitor.cs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Bridge.State;
22
using RLBot.Flat;
33

4+
using Deltas = (float GameTimeDelta, float ArrivalDelta);
5+
46
namespace RLBotCS.ManagerTools;
57

68
public class PerfMonitor
@@ -25,13 +27,13 @@ public class PerfMonitor
2527
B = 0,
2628
};
2729

28-
private readonly CircularBuffer<float> _rlbotSamples = new(_maxSamples);
30+
private readonly CircularBuffer<Deltas> _rlbotSamples = new(_maxSamples);
2931
private readonly SortedDictionary<string, CircularBuffer<bool>> _samples = new();
3032
private float time = 0;
3133

32-
public void AddRLBotSample(float timeDiff)
34+
public void AddRLBotSample(Deltas deltas)
3335
{
34-
_rlbotSamples.AddLast(timeDiff);
36+
_rlbotSamples.AddLast(deltas);
3537
}
3638

3739
public void AddSample(string name, bool gotInput)
@@ -49,18 +51,48 @@ public void RemoveBot(string name)
4951
_samples.Remove(name);
5052
}
5153

54+
public static float GetPercentile(IEnumerable<float> data, float p)
55+
{
56+
var sorted = data.OrderBy(x => x).ToList();
57+
int n = sorted.Count;
58+
if (n == 0) return default;
59+
60+
double rank = p * (n - 1);
61+
int lower = (int)Math.Floor(rank);
62+
int upper = (int)Math.Ceiling(rank);
63+
64+
return (float)(sorted[lower] + (rank - lower) * (sorted[upper] - sorted[lower]));
65+
}
66+
5267
public void RenderSummary(Rendering rendering, GameState gameState, float deltaTime)
5368
{
5469
time += deltaTime;
5570
if (time < _timeSkip)
5671
return;
5772
time = 0;
5873

59-
float averageTimeDiff = _rlbotSamples.Count > 0 ? _rlbotSamples.Iter().Average() : 1;
60-
float timeDiffPercentage = 1 / (120f * averageTimeDiff);
6174

62-
string message = $"RLBot: {timeDiffPercentage * 100:0.0}%";
63-
bool shouldRender = timeDiffPercentage < 0.9999 || timeDiffPercentage > 1.0001;
75+
var arrivalDeltas = _rlbotSamples.Iter().Select(t => t.ArrivalDelta);
76+
var gameTimeDeltas = _rlbotSamples.Iter().Select(t => t.GameTimeDelta);
77+
78+
float averageTickDelta = gameTimeDeltas.Sum() / _maxSamples;
79+
float averageTickRate = 1f / averageTickDelta;
80+
81+
// Find deltas larger than expected at 60hz, allowing 10% margin
82+
float misses60 = arrivalDeltas
83+
.Count(d =>
84+
(d - (1f / 60f)) > (0.1f / 60f));
85+
86+
// Find deltas larger than expected at 120hz, allowing 10% margin
87+
float misses120 = arrivalDeltas
88+
.Count(d =>
89+
(d - (1f / 120f)) > (0.1f / 120f));
90+
91+
string message = $"""
92+
RLBot @ {averageTickRate:0}hz {(1f - misses60 / 120f) * 100f:0}%|{(1f - misses120 / 120f) * 100f:0}%
93+
p95 {GetPercentile(arrivalDeltas, 0.95f) * 1000f:0.0}ms p99 {GetPercentile(arrivalDeltas, 0.99f) * 1000f:0.0}ms
94+
""";
95+
bool shouldRender = misses120 > 1;
6496

6597
foreach (var (name, samples) in _samples)
6698
{

RLBotCS/Server/BridgeHandler.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using System.Threading.Channels;
23
using Bridge.Conversion;
34
using Bridge.TCP;
@@ -57,6 +58,7 @@ private async Task HandleServer()
5758
_context.Logger.LogInformation("Connected to Rocket League");
5859

5960
bool isFirstTick = true;
61+
long lastNewTickTimestamp = Stopwatch.GetTimestamp();
6062

6163
await foreach (var messageClump in _context.Messenger.ReadAllAsync())
6264
{
@@ -95,7 +97,14 @@ private async Task HandleServer()
9597
_context.ticksSinceMapLoad += 1;
9698

9799
if (timeAdvanced)
98-
_context.PerfMonitor.AddRLBotSample(deltaTime);
100+
{
101+
// Only track ticks where time advanced, the api actually sends more
102+
// clumps, but we don't care about those.
103+
float arrivalDeltaTime = (float)Stopwatch.GetElapsedTime(lastNewTickTimestamp).TotalSeconds;
104+
lastNewTickTimestamp = Stopwatch.GetTimestamp();
105+
106+
_context.PerfMonitor.AddRLBotSample((deltaTime, arrivalDeltaTime));
107+
}
99108

100109
ConsiderDistributingPacket(_context, timeAdvanced);
101110

0 commit comments

Comments
 (0)