81da50828b2a6b64f3c2a77402a067b5a49b7492
[platform/core/ml/nnfw.git] / runtime / libs / benchmark / src / Phases.cpp
1 /*
2  * Copyright 2018 The TensorFlow Authors. All Rights Reserved.
3  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include "benchmark/Phases.h"
19 #include "benchmark/Types.h"
20
21 #include <cassert>
22 #include <chrono>
23 #include <iostream>
24 #include <sys/time.h>
25
26 namespace
27 {
28
29 uint64_t nowMicros()
30 {
31   struct timeval tv;
32   gettimeofday(&tv, nullptr);
33   return static_cast<uint64_t>(tv.tv_sec) * 1e6 + tv.tv_usec;
34 }
35
36 void SleepForMicros(uint64_t micros)
37 {
38   timespec sleep_time;
39   sleep_time.tv_sec = micros / 1e6;
40   micros -= sleep_time.tv_sec * 1e6;
41   sleep_time.tv_nsec = micros * 1e3;
42   nanosleep(&sleep_time, nullptr);
43 }
44 }
45
46 namespace benchmark
47 {
48
49 Phases::Phases(const PhaseOption &option)
50     : _option(option),
51       _mem_poll(std::chrono::milliseconds(option.memory_interval), option.memory_gpu)
52 {
53   // DO NOTHING
54 }
55
56 void Phases::run(const std::string &tag, const PhaseFunc &exec, const PhaseFunc *post,
57                  uint32_t loop_num, bool option_disable)
58 {
59   Phase phase{tag, loop_num};
60   PhaseEnum p = getPhaseEnum(tag);
61   for (uint32_t i = 0; i < loop_num; ++i)
62   {
63     if (!option_disable && _option.memory)
64       _mem_poll.start(p);
65
66     uint64_t t = 0u;
67     t = nowMicros();
68
69     exec(phase, i);
70
71     t = nowMicros() - t;
72
73     if (!option_disable && _option.memory)
74       _mem_poll.end(p);
75
76     phase.time.emplace_back(t);
77
78     if (!option_disable && _option.memory)
79     {
80       phase.memory[MemoryType::RSS].emplace_back(_mem_poll.getRssMap().at(p));
81       phase.memory[MemoryType::HWM].emplace_back(_mem_poll.getHwmMap().at(p));
82       phase.memory[MemoryType::PSS].emplace_back(_mem_poll.getPssMap().at(p));
83     }
84
85     if (post)
86       (*post)(phase, i);
87
88     if (_option.run_delay > 0 && p == PhaseEnum::EXECUTE && i != loop_num - 1)
89     {
90       SleepForMicros(_option.run_delay);
91     }
92   }
93
94   if (p == PhaseEnum::END_OF_PHASE)
95   {
96     return;
97   }
98
99   assert(_phases.find(tag) == _phases.end());
100   _phases.emplace(tag, phase);
101 }
102
103 } // namespace benchmark