Back to home page

Project CMSSW displayed by LXR

 
 

    


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 // Function for testing RunningAverage
0008 namespace test_average {
0009   namespace running_average {
0010     int test();
0011   }
0012 }  // namespace test_average
0013 
0014 namespace edm {
0015   // keeps the running average of the last N entries
0016   // thread safe, fast: does not garantee precise update in case of collision
0017   class RunningAverage {
0018     // For tests
0019     friend int ::test_average::running_average::test();
0020 
0021   public:
0022     static constexpr int N = 16;  // better be a power of 2
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     }  // about 2 sigma
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 }  // namespace edm
0052 
0053 #endif