10 static constexpr uint64_t PeriodNanoseconds = 5000000000ULL;
11 static constexpr uint64_t Scale = 65536;
13 void update(uint64_t now, uint32_t active) {
14 if (now < m_LastSample)
16 const uint64_t periods = (now - m_LastSample) / PeriodNanoseconds;
19 m_LastSample += periods * PeriodNanoseconds;
21 const uint32_t decay[] = {60296, 64453, 65173};
22 for (
size_t i = 0; i < 3; ++i) {
23 const uint64_t factor = power(decay[i], periods);
24 const uint64_t target =
static_cast<uint64_t
>(active) * Scale;
25 m_Values[i] = (m_Values[i] * factor + target * (Scale - factor) + Scale / 2) / Scale;
28 void snapshot(uint64_t values[3])
const {
29 for (
size_t i = 0; i < 3; ++i)
30 values[i] = m_Values[i];
34 static uint64_t power(uint64_t base, uint64_t exponent) {
35 uint64_t result = Scale;
39 result = (result * base + Scale / 2) / Scale;
42 base = (base * base + Scale / 2) / Scale;
46 uint64_t m_LastSample = 0;
47 uint64_t m_Values[3] = {};