diff --git a/tensorflow/lite/examples/label_image/label_image.cc b/tensorflow/lite/examples/label_image/label_image.cc index 7c6f523..e458423 100644 --- a/tensorflow/lite/examples/label_image/label_image.cc +++ b/tensorflow/lite/examples/label_image/label_image.cc @@ -24,6 +24,8 @@ limitations under the License. #include #include #include +#include +#include #include // NOLINT(build/include_order) #include // NOLINT(build/include_order) @@ -45,7 +47,7 @@ limitations under the License. namespace tflite { namespace label_image { -double get_us(struct timeval t) { return (t.tv_sec * 1000000 + t.tv_usec); } +double get_us(struct timeval t) { return (t.tv_sec * 1000000.0 + (double)t.tv_usec); } // Takes a file name, and loads a list of labels from it, one per line, and // returns a vector of the strings. It pads with empty strings so the length @@ -87,6 +89,41 @@ void PrintProfilingInfo(const profiling::ProfileEvent* e, uint32_t op_index, << "\n"; } +void LogTimingDistribution(std::vector & timings) { + int timing_count = timings.size(); + int p5_count = timing_count / 20; + std::sort(timings.begin(), timings.end()); + + int i = 0; + int c = 0; + double avg = 0; + for(auto t : timings) { + double ms = t / 1000.0; + avg += ms; + ++i; + ++c; + if (i > p5_count || c == timing_count) { + LOG(INFO) << " => " << (c*100/timing_count) << "% is " << ms << + " ms. avg within bucket: " << (avg/i) << " ms\n"; + i = 0; + avg = 0; + } + } +} + +void LogTimings(std::vector & timings) { + int timing_count = timings.size(); + + int i = 0; + int c = 0; + double avg = 0; + for(auto t : timings) { + double ms = t / 1000.0; + LOG(INFO) << "Iteration_" << c << "=" << ms <<" ms\n"; + ++c; + } +} + void RunInference(Settings* s) { if (!s->model_name.c_str()) { LOG(ERROR) << "no model file name\n"; @@ -188,19 +226,26 @@ void RunInference(Settings* s) { if (s->profiling) profiler->StartProfiling(); - struct timeval start_time, stop_time; + struct timeval start_time, stop_time, act_time; gettimeofday(&start_time, nullptr); + std::vector timings; + double prev_time_us = get_us(start_time); for (int i = 0; i < s->loop_count; i++) { if (interpreter->Invoke() != kTfLiteOk) { LOG(FATAL) << "Failed to invoke tflite!\n"; } + gettimeofday(&act_time, NULL); + double act_time_us = get_us(act_time); + timings.push_back(act_time_us - prev_time_us); + prev_time_us = act_time_us; } gettimeofday(&stop_time, nullptr); LOG(INFO) << "invoked \n"; LOG(INFO) << "average time: " << (get_us(stop_time) - get_us(start_time)) / (s->loop_count * 1000) << " ms \n"; - + LogTimings(timings); + LogTimingDistribution(timings); if (s->profiling) { profiler->StopProfiling(); auto profile_events = profiler->GetProfileEvents();