diff --git a/tensorflow/lite/profiling/BUILD b/tensorflow/lite/profiling/BUILD index 52ea6fe6362..89ad7267820 100644 --- a/tensorflow/lite/profiling/BUILD +++ b/tensorflow/lite/profiling/BUILD @@ -41,6 +41,17 @@ cc_library( copts = common_copts, ) +cc_test( + name = "time_test", + srcs = ["time_test.cc"], + copts = common_copts, + deps = [ + ":time", + "//tensorflow/lite/testing:util", + "@com_google_googletest//:gtest", + ], +) + cc_library( name = "profile_summarizer", srcs = ["profile_summarizer.cc"], diff --git a/tensorflow/lite/profiling/time.cc b/tensorflow/lite/profiling/time.cc index 3e7db03d9d8..32eb30070fb 100644 --- a/tensorflow/lite/profiling/time.cc +++ b/tensorflow/lite/profiling/time.cc @@ -16,8 +16,10 @@ limitations under the License. #if defined(_MSC_VER) #include // NOLINT(build/c++11) +#include // NOLINT(build/c++11) #else #include +#include #endif namespace tflite { @@ -32,12 +34,24 @@ uint64_t NowMicros() { .count(); } +void SleepForMicros(uint64_t micros) { + std::this_thread::sleep_for(std::chrono::microseconds(micros)); +} + #else uint64_t NowMicros() { struct timeval tv; gettimeofday(&tv, nullptr); - return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; + return static_cast(tv.tv_sec) * 1e6 + tv.tv_usec; +} + +void SleepForMicros(uint64_t micros) { + timespec sleep_time; + sleep_time.tv_sec = micros / 1e6; + micros -= sleep_time.tv_sec * 1e6; + sleep_time.tv_nsec = micros * 1e3; + nanosleep(&sleep_time, nullptr); } #endif // defined(_MSC_VER) diff --git a/tensorflow/lite/profiling/time.h b/tensorflow/lite/profiling/time.h index 66233a480fd..c7527ad0d29 100644 --- a/tensorflow/lite/profiling/time.h +++ b/tensorflow/lite/profiling/time.h @@ -21,6 +21,7 @@ namespace tflite { namespace profiling { namespace time { uint64_t NowMicros(); +void SleepForMicros(uint64_t micros); } // namespace time } // namespace profiling } // namespace tflite diff --git a/tensorflow/lite/profiling/time_test.cc b/tensorflow/lite/profiling/time_test.cc new file mode 100644 index 00000000000..6f08479adeb --- /dev/null +++ b/tensorflow/lite/profiling/time_test.cc @@ -0,0 +1,56 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/profiling/time.h" +#include +#include "tensorflow/lite/testing/util.h" + +namespace tflite { +namespace profiling { +namespace time { + +TEST(TimeTest, NowMicros) { + auto now0 = NowMicros(); + EXPECT_GT(now0, 0); + auto now1 = NowMicros(); + EXPECT_GE(now1, now0); +} + +TEST(TimeTest, SleepForMicros) { + // A zero sleep shouldn't cause issues. + SleepForMicros(0); + + // Sleeping should be reflected in the current time. + auto now0 = NowMicros(); + SleepForMicros(50); + auto now1 = NowMicros(); + EXPECT_GE(now1, now0 + 50); + + // Sleeping more than a second should function properly. + now0 = NowMicros(); + SleepForMicros(1e6 + 50); + now1 = NowMicros(); + EXPECT_GE(now1, now0 + 1e6 + 50); +} + +} // namespace time +} // namespace profiling +} // namespace tflite + +int main(int argc, char** argv) { + ::tflite::LogToStderr(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tensorflow/lite/tools/benchmark/benchmark_model.cc b/tensorflow/lite/tools/benchmark/benchmark_model.cc index e9b485efcaa..70f4c94d358 100644 --- a/tensorflow/lite/tools/benchmark/benchmark_model.cc +++ b/tensorflow/lite/tools/benchmark/benchmark_model.cc @@ -15,8 +15,6 @@ limitations under the License. #include "tensorflow/lite/tools/benchmark/benchmark_model.h" -#include - #include #include @@ -28,18 +26,11 @@ void SleepForSeconds(double sleep_seconds) { if (sleep_seconds <= 0.0) { return; } - // Convert the run_delay string into a timespec. - timespec req; - req.tv_sec = static_cast(sleep_seconds); - req.tv_nsec = (sleep_seconds - req.tv_sec) * 1000000000; // If requested, sleep between runs for an arbitrary amount of time. // This can be helpful to determine the effect of mobile processor // scaling and thermal throttling. -#ifdef PLATFORM_WINDOWS - Sleep(sleep_seconds * 1000); -#else - nanosleep(&req, nullptr); -#endif + return tflite::profiling::time::SleepForMicros( + static_cast(sleep_seconds * 1e6)); } } // namespace