Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-23 22:48:06

0001 // -*- C++ -*-
0002 //
0003 // Package:     PerfTools/AllocMonitor
0004 // Class  :     SimpleAllocMonitor
0005 //
0006 // Implementation:
0007 //     [Notes on implementation]
0008 //
0009 // Original Author:  Christopher Jones
0010 //         Created:  Mon, 21 Aug 2023 20:31:57 GMT
0011 //
0012 
0013 // system include files
0014 #include <atomic>
0015 
0016 // user include files
0017 #include "PerfTools/AllocMonitor/interface/AllocMonitorBase.h"
0018 #include "PerfTools/AllocMonitor/interface/AllocMonitorRegistry.h"
0019 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0021 #include "FWCore/ServiceRegistry/interface/ServiceMaker.h"
0022 
0023 namespace {
0024   class MonitorAdaptor : public cms::perftools::AllocMonitorBase {
0025   public:
0026     void allocCalled(size_t iRequested, size_t iActual, void const*) final {
0027       nAllocations_.fetch_add(1, std::memory_order_acq_rel);
0028       requested_.fetch_add(iRequested, std::memory_order_acq_rel);
0029 
0030       //returns previous value
0031       auto a = presentActual_.fetch_add(iActual, std::memory_order_acq_rel);
0032       a += iActual;
0033       auto max = maxActual_.load(std::memory_order_relaxed);
0034       while (a > max) {
0035         if (maxActual_.compare_exchange_strong(max, a, std::memory_order_acq_rel)) {
0036           break;
0037         }
0038       }
0039     }
0040     void deallocCalled(size_t iActual, void const*) final {
0041       nDeallocations_.fetch_add(1, std::memory_order_acq_rel);
0042       auto present = presentActual_.load(std::memory_order_acquire);
0043       if (present >= iActual) {
0044         presentActual_.fetch_sub(iActual, std::memory_order_acq_rel);
0045       }
0046     }
0047 
0048     void performanceReport() const {
0049       auto finalRequested = requested_.load(std::memory_order_acquire);
0050       auto maxActual = maxActual_.load(std::memory_order_acquire);
0051       auto allocs = nAllocations_.load(std::memory_order_acquire);
0052       auto deallocs = nDeallocations_.load(std::memory_order_acquire);
0053 
0054       edm::LogSystem("SimpleAllocMonitor")
0055           << "Memory Report"
0056           << "\n  [monitoring spans the lifetime of Services (first plugins made and last to be deleted)]"
0057           << "\n  total additional memory requested: " << finalRequested
0058           << "\n  max additional memory used: " << maxActual << "\n  # allocations calls:   " << allocs
0059           << "\n  # deallocations calls: " << deallocs;
0060     }
0061 
0062   private:
0063     std::atomic<size_t> requested_ = 0;
0064     std::atomic<size_t> presentActual_ = 0;
0065     std::atomic<size_t> maxActual_ = 0;
0066     std::atomic<size_t> nAllocations_ = 0;
0067     std::atomic<size_t> nDeallocations_ = 0;
0068   };
0069 
0070 }  // namespace
0071 
0072 class SimpleAllocMonitor {
0073 public:
0074   SimpleAllocMonitor()
0075       : adaptor_(cms::perftools::AllocMonitorRegistry::instance().createAndRegisterMonitor<MonitorAdaptor>()) {}
0076 
0077   ~SimpleAllocMonitor() {
0078     adaptor_->performanceReport();
0079     cms::perftools::AllocMonitorRegistry::instance().deregisterMonitor(adaptor_);
0080   }
0081 
0082   MonitorAdaptor* adaptor_;
0083 };
0084 
0085 DEFINE_FWK_SERVICE_MAKER(SimpleAllocMonitor, edm::serviceregistry::NoArgsMaker<SimpleAllocMonitor>);