Skip to content

Commit 45ca7fc

Browse files
authored
Merge pull request #4305 from secondlife/geenz/frametime-metric-improvements
Add helper functions to frametime metrics.
2 parents db49947 + 6ce487f commit 45ca7fc

File tree

1 file changed

+39
-83
lines changed

1 file changed

+39
-83
lines changed

indra/newview/llviewerstats.cpp

Lines changed: 39 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,38 @@ void LLViewerStats::resetStats()
273273
getRecording().reset();
274274
}
275275

276+
// Helper for calculating Nth percentile with linear interpolation
277+
template<typename T>
278+
T calcPercentile(const std::vector<T>& sorted, double percent)
279+
{
280+
if (sorted.empty())
281+
return T(0);
282+
double idx = percent * (sorted.size() - 1);
283+
size_t idx_below = static_cast<size_t>(std::floor(idx));
284+
size_t idx_above = static_cast<size_t>(std::ceil(idx));
285+
if (idx_below == idx_above)
286+
return sorted[idx_below];
287+
double weight_above = idx - idx_below;
288+
return sorted[idx_below] * (1.0 - weight_above) + sorted[idx_above] * weight_above;
289+
}
290+
291+
template<typename T>
292+
T calcStddev(const std::vector<T>& values)
293+
{
294+
if (values.size() < 2)
295+
return T(0);
296+
double sum = 0, sq_sum = 0;
297+
for (const auto& v : values)
298+
{
299+
double d = v.value();
300+
sum += d;
301+
sq_sum += d * d;
302+
}
303+
double mean = sum / values.size();
304+
double variance = (sq_sum / values.size()) - (mean * mean);
305+
return T(std::sqrt(variance));
306+
}
307+
276308
void LLViewerStats::updateFrameStats(const F64Seconds time_diff)
277309
{
278310
if (gFrameCount && mLastTimeDiff > (F64Seconds)0.0)
@@ -300,99 +332,23 @@ void LLViewerStats::updateFrameStats(const F64Seconds time_diff)
300332

301333
if (mLastFrameTimeSample >= frameTimeSampleSeconds())
302334
{
303-
// @TODO: This needs to be de-duped and moved into specific functions.
304-
// If we have more than 5 seconds of frame time samples, calculate the stddev, 99th percentile, and 95th percentile.
305335
std::sort(mFrameTimes.begin(), mFrameTimes.end());
306336
std::sort(mFrameTimesJitter.begin(), mFrameTimesJitter.end());
307-
F64Seconds ninety_ninth_percentile;
308-
F64Seconds ninety_fifth_percentile;
309337

310-
// Calculate standard deviation of mFrameTimes
311-
F64Seconds frame_time_stddev(0);
312-
if (mFrameTimes.size() > 1)
313-
{
314-
F64Seconds mean(0);
315-
for (const auto& v : mFrameTimes)
316-
{
317-
mean += v;
318-
}
319-
mean /= (F64)mFrameTimes.size();
320-
321-
F64Seconds variance(0);
322-
for (const auto& v : mFrameTimes)
323-
{
324-
F64Seconds diff = v - mean;
325-
F64 diff_squared;
326-
diff.value(diff_squared);
327-
diff_squared = std::pow(diff_squared, 2);
328-
variance += F64Seconds(diff_squared);
329-
}
330-
variance /= (F64)(mFrameTimes.size() - 1); // Use sample variance (n-1)
331-
F64 val;
332-
variance.value(val);
333-
frame_time_stddev = F64Seconds(std::sqrt(val));
334-
}
338+
// Use new helpers for calculations
339+
F64Seconds frame_time_stddev = calcStddev(mFrameTimes);
335340
sample(LLStatViewer::FRAMETIME_STDDEV, frame_time_stddev);
336341

337-
if (mFrameTimes.size() > 0)
338-
{
339-
size_t n = mFrameTimes.size();
340-
size_t ninety_ninth_index = (size_t)(n * 0.99);
341-
size_t ninety_fifth_index = (size_t)(n * 0.95);
342-
if (ninety_ninth_index < n)
343-
{
344-
ninety_ninth_percentile = mFrameTimes[ninety_ninth_index];
345-
}
346-
if (ninety_fifth_index < n)
347-
{
348-
ninety_fifth_percentile = mFrameTimes[ninety_fifth_index];
349-
}
350-
}
342+
F64Seconds ninety_ninth_percentile = calcPercentile(mFrameTimes, 0.99);
343+
F64Seconds ninety_fifth_percentile = calcPercentile(mFrameTimes, 0.95);
351344
sample(LLStatViewer::FRAMETIME_99TH, ninety_ninth_percentile);
352345
sample(LLStatViewer::FRAMETIME_95TH, ninety_fifth_percentile);
353346

354-
ninety_ninth_percentile = F64Seconds(0);
355-
ninety_fifth_percentile = F64Seconds(0);
356-
frame_time_stddev = F64Seconds(0);
357-
if (mFrameTimesJitter.size() > 1)
358-
{
359-
F64Seconds mean(0);
360-
for (const auto& v : mFrameTimesJitter)
361-
{
362-
mean += v;
363-
}
364-
mean /= (F64)mFrameTimesJitter.size();
365-
366-
F64Seconds variance(0);
367-
for (const auto& v : mFrameTimesJitter)
368-
{
369-
F64Seconds diff = v - mean;
370-
F64 diff_squared;
371-
diff.value(diff_squared);
372-
diff_squared = std::pow(diff_squared, 2);
373-
variance += F64Seconds(diff_squared);
374-
}
375-
variance /= (F64)(mFrameTimesJitter.size() - 1); // Use sample variance (n-1)
376-
F64 val;
377-
variance.value(val);
378-
frame_time_stddev = F64Seconds(std::sqrt(val));
379-
}
347+
frame_time_stddev = calcStddev(mFrameTimesJitter);
380348
sample(LLStatViewer::FRAMETIME_JITTER_STDDEV, frame_time_stddev);
381349

382-
if (mFrameTimesJitter.size() > 0)
383-
{
384-
size_t n = mFrameTimesJitter.size();
385-
size_t ninety_ninth_index = (size_t)(n * 0.99);
386-
size_t ninety_fifth_index = (size_t)(n * 0.95);
387-
if (ninety_ninth_index < n)
388-
{
389-
ninety_ninth_percentile = mFrameTimesJitter[ninety_ninth_index];
390-
}
391-
if (ninety_fifth_index < n)
392-
{
393-
ninety_fifth_percentile = mFrameTimesJitter[ninety_fifth_index];
394-
}
395-
}
350+
ninety_ninth_percentile = calcPercentile(mFrameTimesJitter, 0.99);
351+
ninety_fifth_percentile = calcPercentile(mFrameTimesJitter, 0.95);
396352
sample(LLStatViewer::FRAMETIME_JITTER_99TH, ninety_ninth_percentile);
397353
sample(LLStatViewer::FRAMETIME_JITTER_95TH, ninety_fifth_percentile);
398354

0 commit comments

Comments
 (0)