00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <iostream>
00030 #include <string.h>
00031 #include <map>
00032 #include <stdint.h>
00033 #include "NvElementProfiler.h"
00034
00035 #define LOCK() pthread_mutex_lock(&profiler_lock)
00036 #define UNLOCK() pthread_mutex_unlock(&profiler_lock)
00037
00038 #define RETURN_IF_DISABLED() \
00039 if (!enabled) { \
00040 UNLOCK(); \
00041 return; \
00042 }
00043
00044 #define GET_TIME(timeval) gettimeofday(timeval, NULL);
00045
00046 #define TIMESPEC_DIFF_USEC(timespec1, timespec2) \
00047 (((timespec1)->tv_sec - (timespec2)->tv_sec) * 1000000L + \
00048 (timespec1)->tv_usec - (timespec2)->tv_usec)
00049
00050 using namespace std;
00051
00052 NvElementProfiler::NvElementProfiler(ProfilerField fields)
00053 :valid_fields(fields)
00054 {
00055 enabled = false;
00056 unit_id_counter = 0;
00057
00058 reset();
00059
00060 pthread_mutex_init(&profiler_lock, NULL);
00061 }
00062
00063 NvElementProfiler::~NvElementProfiler()
00064 {
00065 LOCK();
00066 reset();
00067 UNLOCK();
00068 pthread_mutex_destroy(&profiler_lock);
00069 }
00070 void
00071 NvElementProfiler::enableProfiling(bool reset_data)
00072 {
00073 LOCK();
00074 if (enabled)
00075 {
00076 UNLOCK();
00077 return;
00078 }
00079
00080 if(reset_data)
00081 {
00082 reset();
00083 }
00084
00085 enabled = true;
00086 UNLOCK();
00087 }
00088
00089 void
00090 NvElementProfiler::disableProfiling()
00091 {
00092 LOCK();
00093 RETURN_IF_DISABLED();
00094
00095 data_int.accumulated_time.tv_sec +=
00096 (data_int.stop_time.tv_sec - data_int.start_time.tv_sec);
00097 data_int.accumulated_time.tv_usec +=
00098 (data_int.stop_time.tv_usec - data_int.start_time.tv_usec);
00099 data_int.start_time.tv_sec = 0;
00100 data_int.start_time.tv_usec = 0;
00101 data_int.stop_time.tv_sec = 0;
00102 data_int.stop_time.tv_usec = 0;
00103 enabled = false;
00104 UNLOCK();
00105 }
00106
00107 void NvElementProfiler::getProfilerData(NvElementProfiler::NvElementProfilerData &data)
00108 {
00109 uint64_t total_time;
00110
00111 LOCK();
00112
00113 total_time = data_int.accumulated_time.tv_sec * 1000000L +
00114 data_int.accumulated_time.tv_usec +
00115 TIMESPEC_DIFF_USEC(&data_int.stop_time, &data_int.start_time);
00116
00117 if (data_int.total_processed_units == 0 || total_time == 0)
00118 {
00119 data.average_fps = 0;
00120 }
00121 else
00122 {
00123 data.average_fps = ((float) (data_int.total_processed_units - 1)) *
00124 1000000 / total_time;
00125 }
00126
00127 if (data_int.total_processed_units == 0)
00128 {
00129 data.max_latency_usec = 0;
00130 data.min_latency_usec = 0;
00131 data.average_latency_usec = 0;
00132 }
00133 else
00134 {
00135 data.max_latency_usec = data_int.max_latency_usec;
00136 data.min_latency_usec = data_int.min_latency_usec;
00137 data.average_latency_usec =
00138 data_int.total_latency / data_int.total_processed_units;
00139 }
00140
00141 data.profiling_time.tv_sec =
00142 data_int.accumulated_time.tv_sec + data_int.stop_time.tv_sec -
00143 data_int.start_time.tv_sec;
00144
00145 data.profiling_time.tv_usec =
00146 data_int.accumulated_time.tv_usec + data_int.stop_time.tv_usec -
00147 data_int.start_time.tv_usec;
00148
00149 if (data.profiling_time.tv_usec < 0)
00150 {
00151 data.profiling_time.tv_usec += 1000000;
00152 data.profiling_time.tv_sec--;
00153 }
00154
00155 if (data.profiling_time.tv_usec > 1000000)
00156 {
00157 data.profiling_time.tv_usec -= 1000000;
00158 data.profiling_time.tv_sec++;
00159 }
00160
00161 data.total_processed_units = data_int.total_processed_units;
00162 data.num_late_units = data_int.num_late_units;
00163 data.valid_fields = valid_fields;
00164 UNLOCK();
00165 }
00166
00167 void NvElementProfiler::printProfilerData(ostream &out_stream)
00168 {
00169 NvElementProfilerData data;
00170 getProfilerData(data);
00171
00172 if (data.valid_fields & PROFILER_FIELD_FPS)
00173 {
00174 out_stream << "Total Profiling time = " <<
00175 (data.profiling_time.tv_sec +
00176 (data.profiling_time.tv_usec / 1000000.0)) << endl;
00177 out_stream << "Average FPS = " << data.average_fps << endl;
00178 }
00179 if (data.valid_fields & PROFILER_FIELD_TOTAL_UNITS)
00180 {
00181 out_stream << "Total units processed = " <<
00182 data.total_processed_units << endl;
00183 }
00184 if (data.valid_fields & PROFILER_FIELD_LATE_UNITS)
00185 {
00186 out_stream << "Num. of late units = " <<
00187 data.num_late_units << endl;
00188 }
00189 if (data.valid_fields & PROFILER_FIELD_LATENCIES)
00190 {
00191 out_stream << "Average latency(usec) = " <<
00192 data.average_latency_usec << endl;
00193 out_stream << "Minimum latency(usec) = " <<
00194 data.min_latency_usec << endl;
00195 out_stream << "Maximum latency(usec) = " <<
00196 data.max_latency_usec << endl;
00197 }
00198 }
00199
00200 void
00201 NvElementProfiler::reset()
00202 {
00203 memset(&data_int, 0, sizeof(data_int));
00204 data_int.min_latency_usec = (uint64_t) -1;
00205
00206 unit_start_time_queue.clear();
00207 }
00208
00209 uint64_t
00210 NvElementProfiler::startProcessing()
00211 {
00212 struct timeval time;
00213 uint64_t ret = 0;
00214 LOCK();
00215 if (enabled)
00216 {
00217 std::map<uint64_t,struct timeval>::iterator it =
00218 unit_start_time_queue.end();
00219
00220 unit_id_counter++;
00221 GET_TIME(&time);
00222
00223 unit_start_time_queue.insert(it,
00224 std::pair<uint64_t,struct timeval>(unit_id_counter, time));
00225
00226 ret = unit_id_counter;
00227 }
00228 UNLOCK();
00229 return ret;
00230 }
00231
00232 void
00233 NvElementProfiler::finishProcessing(uint64_t id, bool is_late)
00234 {
00235 struct timeval unit_start_time;
00236 struct timeval stop_time;
00237 uint64_t latency;
00238
00239 LOCK();
00240 RETURN_IF_DISABLED();
00241
00242 if ((valid_fields & PROFILER_FIELD_LATENCIES) &&
00243 unit_start_time_queue.empty())
00244 {
00245 UNLOCK();
00246 return;
00247 }
00248
00249 GET_TIME(&stop_time);
00250
00251 if (valid_fields & PROFILER_FIELD_LATENCIES)
00252 {
00253 std::map<uint64_t, struct timeval>::iterator it;
00254 if (id)
00255 {
00256 it = unit_start_time_queue.find(id);
00257 }
00258 else
00259 {
00260 it = unit_start_time_queue.begin();
00261 }
00262
00263 if (it == unit_start_time_queue.end())
00264 {
00265 UNLOCK();
00266 return;
00267 }
00268 unit_start_time = it->second;
00269 unit_start_time_queue.erase(it);
00270
00271 latency = TIMESPEC_DIFF_USEC(&stop_time, &unit_start_time);
00272 data_int.total_latency += latency;
00273
00274 if (latency < data_int.min_latency_usec)
00275 {
00276 data_int.min_latency_usec = latency;
00277 }
00278 if(latency > data_int.max_latency_usec)
00279 {
00280 data_int.max_latency_usec = latency;
00281 }
00282 }
00283
00284 data_int.stop_time = stop_time;
00285
00286 if (!data_int.start_time.tv_sec && !data_int.start_time.tv_usec)
00287 {
00288 data_int.start_time = data_int.stop_time;
00289 }
00290
00291 if (is_late)
00292 {
00293 data_int.num_late_units++;
00294 }
00295 data_int.total_processed_units++;
00296
00297 UNLOCK();
00298 }