• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
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 #include "runtime/timing.h"
17 
18 #include <iomanip>
19 
20 #include "utils/logger.h"
21 
22 namespace panda {
23 
24 constexpr uint64_t NS_PER_SECOND = 1000000000;
25 constexpr uint64_t NS_PER_MILLISECOND = 1000000;
26 constexpr uint64_t NS_PER_MICROSECOND = 1000;
27 
PrettyTimeNs(uint64_t duration)28 PandaString Timing::PrettyTimeNs(uint64_t duration)
29 {
30     uint64_t time_uint;
31     PandaString time_uint_name;
32     uint64_t main_part;
33     uint64_t fractional_part;
34     if (duration > NS_PER_SECOND) {
35         time_uint = NS_PER_SECOND;
36         main_part = duration / time_uint;
37         fractional_part = duration % time_uint / NS_PER_MILLISECOND;
38         time_uint_name = "s";
39     } else if (duration > NS_PER_MILLISECOND) {
40         time_uint = NS_PER_MILLISECOND;
41         main_part = duration / time_uint;
42         fractional_part = duration % time_uint / NS_PER_MICROSECOND;
43         time_uint_name = "ms";
44     } else {
45         time_uint = NS_PER_MICROSECOND;
46         main_part = duration / time_uint;
47         fractional_part = duration % time_uint;
48         time_uint_name = "us";
49     }
50     PandaStringStream ss;
51     constexpr size_t FRACTION_WIDTH = 3U;
52     ss << main_part << "." << std::setfill('0') << std::setw(FRACTION_WIDTH) << fractional_part << time_uint_name;
53     return ss.str();
54 }
55 
Process()56 void Timing::Process()
57 {
58     PandaStack<PandaVector<TimeLabel>::iterator> label_stack;
59     // NOLINTNEXTLINE(modernize-loop-convert)
60     for (auto it = labels_.begin(); it != labels_.end(); it++) {
61         if (it->GetType() == TimeLabelType::BEGIN) {
62             label_stack.push(it);
63             continue;
64         }
65         auto begin_it = label_stack.top();
66         label_stack.pop();
67         uint64_t duration = it->GetTime() - begin_it->GetTime();
68         uint64_t cpu_duration = it->GetCPUTime() - begin_it->GetCPUTime();
69         begin_it->SetTime(duration);
70         begin_it->SetCPUTime(cpu_duration);
71     }
72 }
73 
Dump()74 PandaString Timing::Dump()
75 {
76     Process();
77     PandaStringStream ss;
78     std::string indent = "    ";
79     size_t indent_count = 0;
80     for (auto &label : labels_) {
81         if (label.GetType() == TimeLabelType::BEGIN) {
82             for (size_t i = 0; i < indent_count; i++) {
83                 ss << indent;
84             }
85             ss << label.GetName() << " " << PrettyTimeNs(label.GetCPUTime()) << "/" << PrettyTimeNs(label.GetTime())
86                << std::endl;
87             indent_count++;
88             continue;
89         }
90         if (indent_count > 0U) {
91             indent_count--;
92         }
93     }
94     return ss.str();
95 }
96 
97 }  // namespace panda
98