17 #include "perf_estimator.h"
22 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__MACH__) && defined(__APPLE__))
24 #include <sys/resource.h>
25 #include <sys/times.h>
28 #error "Cannot compile file because of an unknown method to retrieve OS time."
33 using namespace sc_core;
35 SC_HAS_PROCESS(perf_estimator);
39 , beat_delay(beat_delay_) {
41 if(beat_delay.value()) {
46 perf_estimator::~perf_estimator() {
49 SCCINFO(
"perf_estimator") <<
"constr & elab time: " << (eoe.proc_clock_stamp - soc.proc_clock_stamp) <<
"s";
50 SCCINFO(
"perf_estimator") <<
"simulation time: " << (eos.proc_clock_stamp - sos.proc_clock_stamp) <<
"s";
51 if(cycle_period.value()) {
52 uint64_t cycles = sc_time_stamp().value() / cycle_period.value();
53 SCCINFO(
"perf_estimator") <<
"simulation speed: "
54 << (sc_time_stamp().value() ? cycles / (eos.proc_clock_stamp - soc.proc_clock_stamp) : 0.0)
57 SCCINFO(
"perf_estimator") <<
"max resident memory: " << max_memory <<
"kB";
60 void perf_estimator::end_of_elaboration() { eoe.set(); }
62 void perf_estimator::start_of_simulation() {
67 void perf_estimator::end_of_simulation() {
69 sc_time now = sc_time_stamp();
70 unsigned long long elapsed_wall = (eos.wall_clock_stamp - sos.wall_clock_stamp).total_microseconds();
71 auto elapsed_proc = (
unsigned long long)((eos.proc_clock_stamp - sos.proc_clock_stamp) * 1000000);
72 auto elapsed_sim = (
unsigned long long)(now.to_seconds() * 1000000.);
74 double wall_perf = elapsed_wall / elapsed_sim;
75 double proc_perf = elapsed_proc / elapsed_sim;
76 SCCINFO(
"perf_estimator") <<
"Wall clock (process clock) based simulation real time factor is " << wall_perf <<
"(" << proc_perf
82 void perf_estimator::beat() {
83 if(sc_time_stamp().value())
84 SCCINFO(
"perf_estimator") <<
"Heart beat, rss mem: " << get_memory() <<
"kB";
85 next_trigger(beat_delay);
92 auto scc::perf_estimator::time_stamp::get_cpu_time() ->
double {
98 if(GetProcessTimes(GetCurrentProcess(), &create_time, &exit_time, &kernel_time, &user_time) != -1) {
99 SYSTEMTIME system_time;
100 if(FileTimeToSystemTime(&user_time, &system_time) != -1)
101 return (
double)system_time.wHour * 3600.0 + (double)system_time.wMinute * 60.0 + (
double)system_time.wSecond +
102 (double)system_time.wMilliseconds / 1000.;
104 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__MACH__) && defined(__APPLE__))
105 #if _POSIX_TIMERS > 0
108 struct timespec stamp {};
109 #if _POSIX_CPUTIME > 0
110 if(clock_getcpuclockid(0, &
id) == -1)
112 #
if defined(CLOCK_PROCESS_CPUTIME_ID)
113 id = CLOCK_PROCESS_CPUTIME_ID;
114 #elif defined(CLOCK_VIRTUAL)
119 if(
id != (clockid_t)-1 && clock_gettime(
id, &stamp) != -1)
120 return (
double)stamp.tv_sec + (double)stamp.tv_nsec / 1000000000.0;
123 #if defined(RUSAGE_SELF)
125 struct rusage usage {};
126 if(getrusage(RUSAGE_SELF, &usage) != -1)
127 return (
double)usage.ru_utime.tv_sec + (double)usage.ru_utime.tv_usec / 1000000.0;
130 #if defined(_SC_CLK_TICK)
132 const double ticks = (double)sysconf(_SC_CLK_TCK);
134 if(times(&s) != (clock_t)-1)
135 return (
double)s.tms_utime / ticks;
138 #if defined(CLOCKS_PER_SEC)
142 return (
double)c / (double)CLOCKS_PER_SEC;
149 long scc::perf_estimator::get_memory() {
150 #if defined(RUSAGE_SELF)
152 struct rusage usage {};
153 if(getrusage(RUSAGE_SELF, &usage) != -1) {
154 max_memory = std::max(max_memory, usage.ru_maxrss);
155 return usage.ru_maxrss;
perf_estimator()
default constructor creating an unnamed perf_estimator