JeVois  1.22
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
Timer.C
Go to the documentation of this file.
1// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2//
3// JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4// California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5//
6// This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7// redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8// Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10// License for more details. You should have received a copy of the GNU General Public License along with this program;
11// if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12//
13// Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14// Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16/*! \file */
17
18#include <jevois/Debug/Timer.H>
19#include <jevois/Debug/Log.H>
20#include <jevois/Util/Utils.H>
21#include <sstream>
22#include <iomanip>
23#include <fstream>
24
25#define _BSD_SOURCE /* See feature_test_macros(7) */
26#include <stdlib.h> // for getloadavg()
27
28// ####################################################################################################
29jevois::Timer::Timer(char const * prefix, size_t interval, int loglevel) :
30 itsPrefix(prefix), itsInterval(interval), itsLogLevel(loglevel), itsCount(0),
31 itsStartTime(std::chrono::steady_clock::now()), itsSecs(0.0),
32 itsMinSecs(1.0e30), itsMaxSecs(-1.0e30), itsStr("-- fps, --% CPU"),
33 itsStartTimeForCpu(std::chrono::steady_clock::now())
34{
35 if (interval == 0) LFATAL("Interval must be > 0");
36 getrusage(RUSAGE_SELF, &itsStartRusage);
37}
38
39// ####################################################################################################
41{
42 itsStartTime = std::chrono::steady_clock::now();
43 if (itsCount == 0) { getrusage(RUSAGE_SELF, &itsStartRusage); itsStartTimeForCpu = itsStartTime; }
44}
45
46// ####################################################################################################
47std::string const & jevois::Timer::stop(double * seconds)
48{
49 std::chrono::duration<double> const dur = std::chrono::steady_clock::now() - itsStartTime;
50 double secs = dur.count();
51 if (seconds) *seconds = secs;
52
53 // Update average duration computation:
54 itsSecs += secs; ++itsCount;
55
56 // Update min and max:
57 if (secs < itsMinSecs) itsMinSecs = secs;
58 if (secs > itsMaxSecs) itsMaxSecs = secs;
59
60 if (itsCount >= itsInterval)
61 {
62 double avgsecs = itsSecs / itsInterval;
63 std::ostringstream ss;
64 ss << itsPrefix;
65 if (itsLogLevel != -1) ss << " average (" << itsInterval << ") duration ";
66 jevois::secs2str(ss, avgsecs);
67 ss << " ["; jevois::secs2str(ss, itsMinSecs); ss << " .. "; jevois::secs2str(ss, itsMaxSecs); ss<< ']';
68
69 float fps = 0.0F;
70 if (avgsecs > 0.0) { fps = 1.0F / float(avgsecs); ss << " (" << fps << " fps)"; }
71
72 switch (itsLogLevel)
73 {
74 case LOG_INFO: LINFO(ss.str()); break;
75 case LOG_ERR: LERROR(ss.str()); break;
76 case LOG_CRIT: LFATAL(ss.str()); break;
77 case -1: itsStr = ss.str(); break; // We want to get the elapsed time instead of fps/cpu/temps/etc:
78 default: LDEBUG(ss.str());
79 }
80
81 if (itsLogLevel != -1)
82 {
83 // Compute percent CPU used: since often we only run a chunk of code between start() and stop() that we want to
84 // evaluate, we cannot use itsSecs is as a denominator, we need the total elapsed time since the first call to
85 // start() over the current interval, hence our use of itsStartTimeForCpu here. Hence, note that the CPU load
86 // reported is for the whole process that is running, not just for the critical chunk of code that is executed
87 // between start() and stop(). Indeed the goal is to get an idea of the overall machine utilization:
88 rusage stoprusage; getrusage(RUSAGE_SELF, &stoprusage);
89
90 double const user_secs = double(stoprusage.ru_utime.tv_sec) - double(itsStartRusage.ru_utime.tv_sec) +
91 (double(stoprusage.ru_utime.tv_usec) - double(itsStartRusage.ru_utime.tv_usec)) / 1000000.0;
92
93 std::chrono::duration<double> const cpudur = std::chrono::steady_clock::now() - itsStartTimeForCpu;
94
95 double const cpu = 100.0 * user_secs / cpudur.count();
96
97#ifdef JEVOIS_PLATFORM_PRO
98 // One JeVois Pro, use cpu 2 (big core) and thermal zone 1:
99 static char const tempname[] = "/sys/class/thermal/thermal_zone1/temp";
100 static char const freqname[] = "/sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_cur_freq";
101 int freq = 2208;
102#else
103 static char const tempname[] = "/sys/class/thermal/thermal_zone0/temp";
104 static char const freqname[] = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq";
105 int freq = 1344;
106#endif
107
108 // Get the CPU temperature:
109 int temp = 30;
110 std::ifstream ifs(tempname);
111 if (ifs.is_open())
112 {
113 try { std::string t; std::getline(ifs, t); temp = std::stoi(t); }
114 catch (...) { } // silently ignore any exception and keep default temp if any
115 ifs.close();
116 }
117
118 // Most hosts report milli-degrees, JeVois-A33 platform reports straight degrees:
119#ifndef JEVOIS_PLATFORM_A33
120 temp /= 1000;
121#endif
122
123 // Finally get the CPU frequency:
124 std::ifstream ifs2(freqname);
125 if (ifs2.is_open())
126 {
127 try { std::string f; std::getline(ifs2, f); freq = std::stoi(f) / 1000; }
128 catch (...) { } // silently ignore any exception and keep default freq if any
129 ifs2.close();
130 }
131
132 // Ready to return all that info:
133 std::ostringstream os; os << std::fixed << std::setprecision(1) << fps << " fps, " << cpu << "% CPU, "
134 << temp << "C, " << freq << " MHz";
135 itsStr = os.str();
136 }
137
138 // Get ready for the next cycle:
139 itsSecs = 0.0; itsMinSecs = 1.0e30; itsMaxSecs = -1.0e30; itsCount = 0;
140 }
141
142 return itsStr;
143}
144
145// ####################################################################################################
146std::string const & jevois::Timer::stop()
147{ return stop(nullptr); }
148
149// ####################################################################################################
150// ####################################################################################################
151jevois::TimerOne::TimerOne(char const * prefix) :
152 itsPrefix(prefix)
153{ }
154
155// ####################################################################################################
157{
158 itsStartTime = std::chrono::steady_clock::now();
159}
160
161// ####################################################################################################
162std::string jevois::TimerOne::stop(double * seconds)
163{
164 std::chrono::duration<double> const dur = std::chrono::steady_clock::now() - itsStartTime;
165 double secs = dur.count();
166 if (seconds) *seconds = secs;
167
168 std::ostringstream ss;
169 ss << itsPrefix << ": " << std::fixed << std::setprecision(1); jevois::secs2str(ss, secs);
170 if (secs == 0.0) ss << " (INF fps)"; else ss << " (" << 1.0 / secs << "fps)";
171
172 return ss.str();
173}
174
175// ####################################################################################################
177{ return stop(nullptr); }
void start()
Start a time measurement period.
Definition Timer.C:156
TimerOne(char const *prefix)
Constructor.
Definition Timer.C:151
std::string stop()
Same as the other signature of stop() except does not provide seconds, for python bindings.
Definition Timer.C:176
Timer(char const *prefix, size_t interval=100, int loglevel=LOG_INFO)
Constructor.
Definition Timer.C:29
std::string const & stop()
Same as the other signature of stop() except does not provide seconds, for python bindings.
Definition Timer.C:146
void start()
Start a time measurement period.
Definition Timer.C:40
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
Definition Log.H:230
#define LDEBUG(msg)
Convenience macro for users to print out console or syslog messages, DEBUG level.
Definition Log.H:173
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
Definition Log.H:211
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
Definition Log.H:194
std::string secs2str(double secs)
Report a duration given in seconds with variable units (ns, us, ms, or s), with precision of 2 decima...
Definition Utils.C:479