1/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2 3Licensed under the Apache License, Version 2.0 (the "License"); 4you may not use this file except in compliance with the License. 5You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9Unless required by applicable law or agreed to in writing, software 10distributed under the License is distributed on an "AS IS" BASIS, 11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12See the License for the specific language governing permissions and 13limitations under the License. 14==============================================================================*/ 15 16// Utility functions for performance profiling. 17 18#ifndef TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TIME_LOG_H_ 19#define TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TIME_LOG_H_ 20 21#include <stdint.h> 22 23#include "tensorflow/examples/android/jni/object_tracking/logging.h" 24#include "tensorflow/examples/android/jni/object_tracking/utils.h" 25 26#ifdef LOG_TIME 27 28// Blend constant for running average. 29#define ALPHA 0.98f 30#define NUM_LOGS 100 31 32struct LogEntry { 33 const char* id; 34 int64_t time_stamp; 35}; 36 37struct AverageEntry { 38 const char* id; 39 float average_duration; 40}; 41 42// Storage for keeping track of this frame's values. 43extern int num_time_logs; 44extern LogEntry time_logs[NUM_LOGS]; 45 46// Storage for keeping track of average values (each entry may not be printed 47// out each frame). 48extern AverageEntry avg_entries[NUM_LOGS]; 49extern int num_avg_entries; 50 51// Call this at the start of a logging phase. 52inline static void ResetTimeLog() { 53 num_time_logs = 0; 54} 55 56 57// Log a message to be printed out when printTimeLog is called, along with the 58// amount of time in ms that has passed since the last call to this function. 59inline static void TimeLog(const char* const str) { 60 LOGV("%s", str); 61 if (num_time_logs >= NUM_LOGS) { 62 LOGE("Out of log entries!"); 63 return; 64 } 65 66 time_logs[num_time_logs].id = str; 67 time_logs[num_time_logs].time_stamp = CurrentThreadTimeNanos(); 68 ++num_time_logs; 69} 70 71 72inline static float Blend(float old_val, float new_val) { 73 return ALPHA * old_val + (1.0f - ALPHA) * new_val; 74} 75 76 77inline static float UpdateAverage(const char* str, const float new_val) { 78 for (int entry_num = 0; entry_num < num_avg_entries; ++entry_num) { 79 AverageEntry* const entry = avg_entries + entry_num; 80 if (str == entry->id) { 81 entry->average_duration = Blend(entry->average_duration, new_val); 82 return entry->average_duration; 83 } 84 } 85 86 if (num_avg_entries >= NUM_LOGS) { 87 LOGE("Too many log entries!"); 88 } 89 90 // If it wasn't there already, add it. 91 avg_entries[num_avg_entries].id = str; 92 avg_entries[num_avg_entries].average_duration = new_val; 93 ++num_avg_entries; 94 95 return new_val; 96} 97 98 99// Prints out all the timeLog statements in chronological order with the 100// interval that passed between subsequent statements. The total time between 101// the first and last statements is printed last. 102inline static void PrintTimeLog() { 103 LogEntry* last_time = time_logs; 104 105 float average_running_total = 0.0f; 106 107 for (int i = 0; i < num_time_logs; ++i) { 108 LogEntry* const this_time = time_logs + i; 109 110 const float curr_time = 111 (this_time->time_stamp - last_time->time_stamp) / 1000000.0f; 112 113 const float avg_time = UpdateAverage(this_time->id, curr_time); 114 average_running_total += avg_time; 115 116 LOGD("%32s: %6.3fms %6.4fms", this_time->id, curr_time, avg_time); 117 last_time = this_time; 118 } 119 120 const float total_time = 121 (last_time->time_stamp - time_logs->time_stamp) / 1000000.0f; 122 123 LOGD("TOTAL TIME: %6.3fms %6.4fms\n", 124 total_time, average_running_total); 125 LOGD(" "); 126} 127#else 128inline static void ResetTimeLog() {} 129 130inline static void TimeLog(const char* const str) { 131 LOGV("%s", str); 132} 133 134inline static void PrintTimeLog() {} 135#endif 136 137#endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TIME_LOG_H_ 138