• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 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 ark {
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 timeUint;
31     PandaString timeUintName;
32     uint64_t mainPart;
33     uint64_t fractionalPart;
34     if (duration > NS_PER_SECOND) {
35         timeUint = NS_PER_SECOND;
36         mainPart = duration / timeUint;
37         fractionalPart = duration % timeUint / NS_PER_MILLISECOND;
38         timeUintName = "s";
39     } else if (duration > NS_PER_MILLISECOND) {
40         timeUint = NS_PER_MILLISECOND;
41         mainPart = duration / timeUint;
42         fractionalPart = duration % timeUint / NS_PER_MICROSECOND;
43         timeUintName = "ms";
44     } else {
45         timeUint = NS_PER_MICROSECOND;
46         mainPart = duration / timeUint;
47         fractionalPart = duration % timeUint;
48         timeUintName = "us";
49     }
50     PandaStringStream ss;
51     constexpr size_t FRACTION_WIDTH = 3U;
52     ss << mainPart << "." << std::setfill('0') << std::setw(FRACTION_WIDTH) << fractionalPart << timeUintName;
53     return ss.str();
54 }
55 
Process()56 void Timing::Process()
57 {
58     PandaStack<PandaVector<TimeLabel>::iterator> labelStack;
59     // NOLINTNEXTLINE(modernize-loop-convert)
60     for (auto it = labels_.begin(); it != labels_.end(); it++) {
61         if (it->GetType() == TimeLabelType::BEGIN) {
62             labelStack.push(it);
63             continue;
64         }
65         auto beginIt = labelStack.top();
66         labelStack.pop();
67         uint64_t duration = it->GetTime() - beginIt->GetTime();
68         uint64_t cpuDuration = it->GetCPUTime() - beginIt->GetCPUTime();
69         beginIt->SetTime(duration);
70         beginIt->SetCPUTime(cpuDuration);
71     }
72 }
73 
Dump()74 PandaString Timing::Dump()
75 {
76     Process();
77     PandaStringStream ss;
78     std::string indent = "    ";
79     size_t indentCount = 0;
80     for (auto &label : labels_) {
81         if (label.GetType() == TimeLabelType::BEGIN) {
82             for (size_t i = 0; i < indentCount; i++) {
83                 ss << indent;
84             }
85             ss << label.GetName() << " " << PrettyTimeNs(label.GetCPUTime()) << "/" << PrettyTimeNs(label.GetTime())
86                << std::endl;
87             indentCount++;
88             continue;
89         }
90         if (indentCount > 0U) {
91             indentCount--;
92         }
93     }
94     return ss.str();
95 }
96 
97 }  // namespace ark
98