123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- /*
- * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of NVIDIA CORPORATION nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <iostream>
- #include <string.h>
- #include <map>
- #include <stdint.h>
- #include "NvElementProfiler.h"
- #define LOCK() pthread_mutex_lock(&profiler_lock)
- #define UNLOCK() pthread_mutex_unlock(&profiler_lock)
- #define RETURN_IF_DISABLED() \
- if (!enabled) { \
- UNLOCK(); \
- return; \
- }
- #define GET_TIME(timeval) gettimeofday(timeval, NULL);
- #define TIMESPEC_DIFF_USEC(timespec1, timespec2) \
- (((timespec1)->tv_sec - (timespec2)->tv_sec) * 1000000L + \
- (timespec1)->tv_usec - (timespec2)->tv_usec)
- using namespace std;
- NvElementProfiler::NvElementProfiler(ProfilerField fields)
- :valid_fields(fields)
- {
- enabled = false;
- unit_id_counter = 0;
- reset();
- pthread_mutex_init(&profiler_lock, NULL);
- }
- NvElementProfiler::~NvElementProfiler()
- {
- LOCK();
- reset();
- UNLOCK();
- pthread_mutex_destroy(&profiler_lock);
- }
- void
- NvElementProfiler::enableProfiling(bool reset_data)
- {
- LOCK();
- if (enabled)
- {
- UNLOCK();
- return;
- }
- if(reset_data)
- {
- reset();
- }
- enabled = true;
- UNLOCK();
- }
- void
- NvElementProfiler::disableProfiling()
- {
- LOCK();
- RETURN_IF_DISABLED();
- data_int.accumulated_time.tv_sec +=
- (data_int.stop_time.tv_sec - data_int.start_time.tv_sec);
- data_int.accumulated_time.tv_usec +=
- (data_int.stop_time.tv_usec - data_int.start_time.tv_usec);
- data_int.start_time.tv_sec = 0;
- data_int.start_time.tv_usec = 0;
- data_int.stop_time.tv_sec = 0;
- data_int.stop_time.tv_usec = 0;
- enabled = false;
- UNLOCK();
- }
- void NvElementProfiler::getProfilerData(NvElementProfiler::NvElementProfilerData &data)
- {
- uint64_t total_time;
- LOCK();
- total_time = data_int.accumulated_time.tv_sec * 1000000L +
- data_int.accumulated_time.tv_usec +
- TIMESPEC_DIFF_USEC(&data_int.stop_time, &data_int.start_time);
- if (data_int.total_processed_units == 0 || total_time == 0)
- {
- data.average_fps = 0;
- }
- else
- {
- data.average_fps = ((float) (data_int.total_processed_units - 1)) *
- 1000000 / total_time;
- }
- if (data_int.total_processed_units == 0)
- {
- data.max_latency_usec = 0;
- data.min_latency_usec = 0;
- data.average_latency_usec = 0;
- }
- else
- {
- data.max_latency_usec = data_int.max_latency_usec;
- data.min_latency_usec = data_int.min_latency_usec;
- data.average_latency_usec =
- data_int.total_latency / data_int.total_processed_units;
- }
- data.profiling_time.tv_sec =
- data_int.accumulated_time.tv_sec + data_int.stop_time.tv_sec -
- data_int.start_time.tv_sec;
- data.profiling_time.tv_usec =
- data_int.accumulated_time.tv_usec + data_int.stop_time.tv_usec -
- data_int.start_time.tv_usec;
- if (data.profiling_time.tv_usec < 0)
- {
- data.profiling_time.tv_usec += 1000000;
- data.profiling_time.tv_sec--;
- }
- if (data.profiling_time.tv_usec > 1000000)
- {
- data.profiling_time.tv_usec -= 1000000;
- data.profiling_time.tv_sec++;
- }
- data.total_processed_units = data_int.total_processed_units;
- data.num_late_units = data_int.num_late_units;
- data.valid_fields = valid_fields;
- UNLOCK();
- }
- void NvElementProfiler::printProfilerData(ostream &out_stream)
- {
- NvElementProfilerData data;
- getProfilerData(data);
- if (data.valid_fields & PROFILER_FIELD_FPS)
- {
- out_stream << "Total Profiling time = " <<
- (data.profiling_time.tv_sec +
- (data.profiling_time.tv_usec / 1000000.0)) << endl;
- out_stream << "Average FPS = " << data.average_fps << endl;
- }
- if (data.valid_fields & PROFILER_FIELD_TOTAL_UNITS)
- {
- out_stream << "Total units processed = " <<
- data.total_processed_units << endl;
- }
- if (data.valid_fields & PROFILER_FIELD_LATE_UNITS)
- {
- out_stream << "Num. of late units = " <<
- data.num_late_units << endl;
- }
- if (data.valid_fields & PROFILER_FIELD_LATENCIES)
- {
- out_stream << "Average latency(usec) = " <<
- data.average_latency_usec << endl;
- out_stream << "Minimum latency(usec) = " <<
- data.min_latency_usec << endl;
- out_stream << "Maximum latency(usec) = " <<
- data.max_latency_usec << endl;
- }
- }
- void
- NvElementProfiler::reset()
- {
- memset(&data_int, 0, sizeof(data_int));
- data_int.min_latency_usec = (uint64_t) -1;
- unit_start_time_queue.clear();
- }
- uint64_t
- NvElementProfiler::startProcessing()
- {
- struct timeval time;
- uint64_t ret = 0;
- LOCK();
- if (enabled)
- {
- std::map<uint64_t,struct timeval>::iterator it =
- unit_start_time_queue.end();
- unit_id_counter++;
- GET_TIME(&time);
- unit_start_time_queue.insert(it,
- std::pair<uint64_t,struct timeval>(unit_id_counter, time));
- ret = unit_id_counter;
- }
- UNLOCK();
- return ret;
- }
- void
- NvElementProfiler::finishProcessing(uint64_t id, bool is_late)
- {
- struct timeval unit_start_time;
- struct timeval stop_time;
- uint64_t latency;
- LOCK();
- RETURN_IF_DISABLED();
- if ((valid_fields & PROFILER_FIELD_LATENCIES) &&
- unit_start_time_queue.empty())
- {
- UNLOCK();
- return;
- }
- GET_TIME(&stop_time);
- if (valid_fields & PROFILER_FIELD_LATENCIES)
- {
- std::map<uint64_t, struct timeval>::iterator it;
- if (id)
- {
- it = unit_start_time_queue.find(id);
- }
- else
- {
- it = unit_start_time_queue.begin();
- }
- if (it == unit_start_time_queue.end())
- {
- UNLOCK();
- return;
- }
- unit_start_time = it->second;
- unit_start_time_queue.erase(it);
- latency = TIMESPEC_DIFF_USEC(&stop_time, &unit_start_time);
- data_int.total_latency += latency;
- if (latency < data_int.min_latency_usec)
- {
- data_int.min_latency_usec = latency;
- }
- if(latency > data_int.max_latency_usec)
- {
- data_int.max_latency_usec = latency;
- }
- }
- data_int.stop_time = stop_time;
- if (!data_int.start_time.tv_sec && !data_int.start_time.tv_usec)
- {
- data_int.start_time = data_int.stop_time;
- }
- if (is_late)
- {
- data_int.num_late_units++;
- }
- data_int.total_processed_units++;
- UNLOCK();
- }
|