Flutter Engine
The Flutter Engine
compiler_timings.cc
Go to the documentation of this file.
1// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
6
7namespace dart {
8
9namespace {
10#define DEFINE_NAME(Name) #Name,
11const char* timer_names[] = {COMPILER_TIMERS_LIST(DEFINE_NAME)};
12#undef DEFINE_NAME
13
14} // namespace
15
16void CompilerTimings::PrintTimers(
17 Zone* zone,
18 const std::unique_ptr<CompilerTimings::Timers>& timers,
19 const Timer& total,
20 intptr_t level) {
21 const int64_t total_elapsed = total.TotalElapsedTime();
22
23 int64_t total_accounted = 0;
24 int64_t total_accounted_cpu = 0;
25 for (intptr_t i = 0; i < kNumTimers; i++) {
26 const auto& entry = timers->timers_[i];
27 total_accounted += entry.TotalElapsedTime();
28 total_accounted_cpu += entry.TotalElapsedTimeCpu();
29 }
30
31 if (level > 0) {
32 // Print (self: ...) timing on the previous line if our amount of time
33 // spent outside of nested timers is between 1% and 99%.
34 const double kMinInterestingSelfPercent = 1.0;
35 const double kMaxInterestingSelfPercent = 99.0;
36
37 const int64_t self = total_elapsed - total_accounted;
38 const auto self_pct =
39 static_cast<double>(Utils::Abs(self)) * 100 / total_elapsed;
40 if (kMinInterestingSelfPercent < self_pct &&
41 self_pct < kMaxInterestingSelfPercent) {
42 const int64_t self_cpu =
43 total.TotalElapsedTimeCpu() - total_accounted_cpu;
44 const auto self_timer = Timer(self, self_cpu);
45 OS::PrintErr(" (self: [%6.2f%%] %s)\n", self_pct,
46 self_timer.FormatElapsedHumanReadable(zone));
47 } else {
48 OS::PrintErr("\n");
49 }
50 }
51
52 // Sort timers by the amount of time elapsed within each one.
53 Timer* by_elapsed[kNumTimers];
54 for (intptr_t i = 0; i < kNumTimers; i++) {
55 by_elapsed[i] = &timers->timers_[i];
56 }
57 qsort(by_elapsed, kNumTimers, sizeof(Timer*),
58 [](const void* pa, const void* pb) -> int {
59 const auto a_elapsed =
60 (*static_cast<Timer* const*>(pa))->TotalElapsedTime();
61 const auto b_elapsed =
62 (*static_cast<Timer* const*>(pb))->TotalElapsedTime();
63 return b_elapsed < a_elapsed ? -1 : b_elapsed > a_elapsed ? 1 : 0;
64 });
65
66 // Print sorted in descending order.
67 for (intptr_t i = 0; i < kNumTimers; i++) {
68 auto timer = by_elapsed[i];
69 if (timer->TotalElapsedTime() > 0) {
70 const auto timer_id = static_cast<TimerId>(timer - &timers->timers_[0]);
71 const auto pct =
72 static_cast<double>(timer->TotalElapsedTime()) * 100 / total_elapsed;
73 // Must be int for * width specifier.
74 const int indent = static_cast<int>(level * 2);
75
76 // Note: don't emit EOL because PrintTimers can print self timing.
78 "%*s[%6.2f%%] %-*s %-10s", indent, "", pct, 60 - indent,
79 timer_names[timer_id],
80 Timer::FormatElapsedHumanReadable(zone, timer->TotalElapsedTime(),
81 timer->TotalElapsedTimeCpu()));
82
83 // Print nested timers if any or just emit EOL.
84 if (timers->nested_[timer_id] != nullptr) {
85 PrintTimers(zone, timers->nested_[timer_id], *timer, level + 1);
86 } else {
87 OS::PrintErr("\n");
88 }
89 }
90 }
91}
92
94 Zone* zone = Thread::Current()->zone();
95
96 OS::PrintErr("Precompilation took: %s\n",
97 total_.FormatElapsedHumanReadable(zone));
98
99 PrintTimers(zone, root_, total_, 0);
100
101 OS::PrintErr("Inlining by outcome\n Success: %s\n Failure: %s\n",
102 try_inlining_success_.FormatElapsedHumanReadable(zone),
103 try_inlining_failure_.FormatElapsedHumanReadable(zone));
104}
105
106} // namespace dart
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
const char * FormatElapsedHumanReadable(Zone *zone) const
Definition: timer.h:140
static T Abs(T x)
Definition: utils.h:49
#define DEFINE_NAME(Name)
#define COMPILER_TIMERS_LIST(V)
Definition: dart_vm.cc:33