ndmspc v1.2.0-0.1.rc5
Loading...
Searching...
No Matches
NResourceMonitor.cxx
1#include <THnSparse.h>
2#include <TROOT.h>
3#include "NLogger.h"
4#include "NUtils.h"
5#include "NResourceMonitor.h"
6
10
11namespace Ndmspc {
14void NResourceMonitor::Print(Option_t * /*option*/) const
15{
19 double userStart = timevalToDouble(fUsageStart.ru_utime);
20 double sysStart = timevalToDouble(fUsageStart.ru_stime);
21 double userEnd = timevalToDouble(fUsageEnd.ru_utime);
22 double sysEnd = timevalToDouble(fUsageEnd.ru_stime);
23
24 double wallStart = std::chrono::duration<double>(fWallStart.time_since_epoch()).count();
25 double wallEnd = std::chrono::duration<double>(fWallEnd.time_since_epoch()).count();
26
27 NLogInfo("Resource usage:");
28 NLogInfo(" User time: %.6f s", userEnd - userStart);
29 NLogInfo(" System time: %.6f s", sysEnd - sysStart);
30 NLogInfo(" Wall time: %.6f s", wallEnd - wallStart);
31
32 // calculate effective CPU usage
33 NLogInfo(" CPU usage: %.2f %%", GetCpuUsage());
34
35 NLogInfo(" Min RSS: %ld KB", fUsageStart.ru_maxrss);
36 NLogInfo(" Max RSS: %ld KB", fUsageEnd.ru_maxrss);
37 NLogInfo(" Diff RSS: %ld KB", fUsageEnd.ru_maxrss - fUsageStart.ru_maxrss);
38 // NLogInfo(" Minor faults: %ld", fUsageEnd.ru_minflt - fUsageStart.ru_minflt);
39 // NLogInfo(" Major faults: %ld", fUsageEnd.ru_majflt - fUsageStart.ru_majflt);
40}
41
42THnSparse * NResourceMonitor::Initialize(THnSparse * hns)
43{
47 std::vector<TAxis *> axes;
48 int nThreads = ROOT::GetThreadPoolSize();
49 if (nThreads <= 0) nThreads = 1;
50
51 NLogTrace("NResourceMonitor::Initialize: Initializing resource monitor for %d threads", nThreads);
52
53 TAxis * threadAxis = new TAxis(nThreads, 0, nThreads);
54 threadAxis->SetNameTitle("thread", "Thread");
55 // set labels for thread axis
56 for (int i = 0; i < nThreads; ++i) {
57 threadAxis->SetBinLabel(i + 1, TString::Format("%d", i).Data());
58 }
59 axes.push_back(threadAxis);
60 TAxis * aStat = NUtils::CreateAxisFromLabels("stat", "Stat", fNames);
61 axes.push_back(aStat);
62
63 if (fHnSparse) {
64 NLogWarning("NResourceMonitor::Initialize: THnSparse is already initialized, overwriting ...");
65 SafeDelete(fHnSparse);
66 }
67
68 fHnSparse = NUtils::ReshapeSparseAxes(hns, {}, axes);
69 fHnSparse->SetNameTitle("resource_monitor", "Resource Monitor");
70
71 return fHnSparse;
72}
73
74void NResourceMonitor::Fill(Int_t * coords, int threadId)
75{
80 auto statBinCoords = std::make_unique<Int_t[]>(fHnSparse->GetNdimensions());
81 // Int_t statBinCoords[fHnSparse->GetNdimensions()];
82 // set statBinCoords from statHnSparse
83 for (Int_t i = 0; i < fHnSparse->GetNdimensions() - 2; ++i) {
84 statBinCoords[i] = coords[i];
85 }
86 Long64_t statBin;
87
88 // Set thread id coordinate
89 statBinCoords[fHnSparse->GetNdimensions() - 2] = threadId + 1;
90
91 statBinCoords[fHnSparse->GetNdimensions() - 1] = 1;
92 statBin = fHnSparse->GetBin(statBinCoords.get());
93 fHnSparse->SetBinContent(statBin, GetTimeDiffInSeconds());
94
95 // Set CPU usage
96 statBinCoords[fHnSparse->GetNdimensions() - 1] = 2;
97 statBin = fHnSparse->GetBin(statBinCoords.get());
98 fHnSparse->SetBinContent(statBin, GetCpuUsage());
99
100 // Set Memory usage
101 statBinCoords[fHnSparse->GetNdimensions() - 1] = 3;
102 statBin = fHnSparse->GetBin(statBinCoords.get());
103 fHnSparse->SetBinContent(statBin, GetMemoryUsageDiff());
104}
105
107{
108 fWallStart = std::chrono::high_resolution_clock::now();
109 // gather start resource usage
110 if (getrusage(RUSAGE_SELF, &fUsageStart) == -1) {
111 NLogError("NResourceMonitor::Start: getrusage failed at start");
112 }
113}
114
116{
117 fWallEnd = std::chrono::high_resolution_clock::now();
118 // gather resource usage after processing
119 if (getrusage(RUSAGE_SELF, &fUsageEnd) == -1) {
120 NLogError("NResourceMonitor::End: getrusage failed at end");
121 }
122}
124{
125 std::chrono::duration<double> diff = fWallEnd - fWallStart;
126 return diff.count();
127}
128
130{
131
132 double userStart = timevalToDouble(fUsageStart.ru_utime);
133 double sysStart = timevalToDouble(fUsageStart.ru_stime);
134 double userEnd = timevalToDouble(fUsageEnd.ru_utime);
135 double sysEnd = timevalToDouble(fUsageEnd.ru_stime);
136
137 double wallStart = std::chrono::duration<double>(fWallStart.time_since_epoch()).count();
138 double wallEnd = std::chrono::duration<double>(fWallEnd.time_since_epoch()).count();
139
140 double usage = ((userEnd - userStart) + (sysEnd - sysStart)) / (wallEnd - wallStart) * 100.0;
141 return usage;
142}
143
144} // namespace Ndmspc
Monitors and records resource usage (CPU, memory, wall time) for processes or threads.
void Start()
Records the starting resource usage and wall time.
THnSparse * fHnSparse
THnSparse histogram for resource data.
virtual void Print(Option_t *option="") const
Prints the resource monitor information.
double GetTimeDiffInSeconds() const
Returns the time difference in seconds since the last measurement or reset.
std::chrono::high_resolution_clock::time_point fWallStart
Wall clock start time.
void End()
Records the ending resource usage and wall time.
virtual ~NResourceMonitor()
Destructor.
double timevalToDouble(const timeval &tv) const
Helper function to convert timeval to double seconds.
std::vector< std::string > fNames
Axis names.
void Fill(Int_t *coords, int threadId)
Fills resource usage data into the histogram.
double GetCpuUsage() const
Calculates and returns the CPU usage between Start and End.
THnSparse * Initialize(THnSparse *hns)
Initializes the THnSparse histogram for resource data.
NResourceMonitor()
Default constructor.
rusage fUsageStart
Resource usage at start.
rusage fUsageEnd
Resource usage at end.
std::chrono::high_resolution_clock::time_point fWallEnd
Wall clock end time.
long GetMemoryUsageDiff() const
Returns the difference in memory usage (in kilobytes) between Start and End.
static THnSparse * ReshapeSparseAxes(THnSparse *hns, std::vector< int > order, std::vector< TAxis * > newAxes={}, std::vector< int > newPoint={}, Option_t *option="E")
Reshape axes of THnSparse.
Definition NUtils.cxx:452
static TAxis * CreateAxisFromLabels(const std::string &name, const std::string &title, const std::vector< std::string > &labels)
Create a TAxis from a list of labels.
Definition NUtils.cxx:185
Global callback function for libwebsockets client events.