File indexing completed on 2024-04-06 12:13:12
0001 #ifndef FWCore_Utilities_RunningAverage_H
0002 #define FWCore_Utilities_RunningAverage_H
0003 #include <atomic>
0004 #include <algorithm>
0005 #include <array>
0006
0007
0008 namespace test_average {
0009 namespace running_average {
0010 int test();
0011 }
0012 }
0013
0014 namespace edm {
0015
0016
0017 class RunningAverage {
0018
0019 friend int ::test_average::running_average::test();
0020
0021 public:
0022 static constexpr int N = 16;
0023 explicit RunningAverage(unsigned int k = 4) : m_mean(N * k), m_curr(0) {
0024 for (auto& i : m_buffer)
0025 i = k;
0026 }
0027
0028 int mean() const { return m_mean / N; }
0029
0030 int upper() const {
0031 auto lm = mean();
0032 return lm + (std::abs(m_buffer[0] - lm) + std::abs(m_buffer[N / 2] - lm));
0033 }
0034
0035 void update(unsigned int q) {
0036 int e = m_curr;
0037 while (!m_curr.compare_exchange_weak(e, e + 1))
0038 ;
0039 int k = (N - 1) & e;
0040 int old = m_buffer[k];
0041 if (!m_buffer[k].compare_exchange_strong(old, q))
0042 return;
0043 m_mean += (q - old);
0044 }
0045
0046 private:
0047 std::array<std::atomic<int>, N> m_buffer;
0048 std::atomic<int> m_mean;
0049 std::atomic<int> m_curr;
0050 };
0051 }
0052
0053 #endif