1 /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations 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/tools/android/test/jni/object_tracking/logging.h"
24 #include "tensorflow/tools/android/test/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
32 struct LogEntry {
33 const char* id;
34 int64_t time_stamp;
35 };
36
37 struct AverageEntry {
38 const char* id;
39 float average_duration;
40 };
41
42 // Storage for keeping track of this frame's values.
43 extern int num_time_logs;
44 extern LogEntry time_logs[NUM_LOGS];
45
46 // Storage for keeping track of average values (each entry may not be printed
47 // out each frame).
48 extern AverageEntry avg_entries[NUM_LOGS];
49 extern int num_avg_entries;
50
51 // Call this at the start of a logging phase.
ResetTimeLog()52 inline 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.
TimeLog(const char * const str)59 inline 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
Blend(float old_val,float new_val)72 inline static float Blend(float old_val, float new_val) {
73 return ALPHA * old_val + (1.0f - ALPHA) * new_val;
74 }
75
76
UpdateAverage(const char * str,const float new_val)77 inline 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.
PrintTimeLog()102 inline 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
ResetTimeLog()128 inline static void ResetTimeLog() {}
129
TimeLog(const char * const str)130 inline static void TimeLog(const char* const str) {
131 LOGV("%s", str);
132 }
133
PrintTimeLog()134 inline static void PrintTimeLog() {}
135 #endif
136
137 #endif // TENSORFLOW_EXAMPLES_ANDROID_JNI_OBJECT_TRACKING_TIME_LOG_H_
138