• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "powerhal-adaptivecpu"
18 #define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
19 
20 #include "AdaptiveCpuStats.h"
21 
22 #include <utils/Trace.h>
23 
24 #include "AdaptiveCpu.h"
25 
26 using std::chrono_literals::operator""ns;
27 
28 namespace aidl {
29 namespace google {
30 namespace hardware {
31 namespace power {
32 namespace impl {
33 namespace pixel {
34 
RegisterStartRun()35 void AdaptiveCpuStats::RegisterStartRun() {
36     ATRACE_CALL();
37     mNumStartedRuns++;
38     mLastRunStartTime = mTimeSource->GetTime();
39     if (mStartTime == 0ns) {
40         mStartTime = mLastRunStartTime;
41     }
42 }
43 
RegisterSuccessfulRun(ThrottleDecision previousThrottleDecision,ThrottleDecision throttleDecision,WorkDurationFeatures workDurationFeatures,const AdaptiveCpuConfig & config)44 void AdaptiveCpuStats::RegisterSuccessfulRun(ThrottleDecision previousThrottleDecision,
45                                              ThrottleDecision throttleDecision,
46                                              WorkDurationFeatures workDurationFeatures,
47                                              const AdaptiveCpuConfig &config) {
48     ATRACE_CALL();
49     mNumSuccessfulRuns++;
50     mNumThrottles[throttleDecision]++;
51     const auto runSuccessTime = mTimeSource->GetTime();
52     mTotalRunDuration += runSuccessTime - mLastRunStartTime;
53     // Don't update previousThrottleDecision entries if we haven't run successfully before.
54     if (mLastRunSuccessTime != 0ns) {
55         mThrottleDurations[previousThrottleDecision] +=
56                 std::min(runSuccessTime - mLastRunSuccessTime,
57                          std::chrono::duration_cast<std::chrono::nanoseconds>(config.hintTimeout));
58         mNumDurations[previousThrottleDecision] += workDurationFeatures.numDurations;
59         mNumMissedDeadlines[previousThrottleDecision] += workDurationFeatures.numMissedDeadlines;
60     }
61     mLastRunSuccessTime = runSuccessTime;
62 }
63 
DumpToStream(std::ostream & stream) const64 void AdaptiveCpuStats::DumpToStream(std::ostream &stream) const {
65     stream << "Stats:\n";
66     stream << "- Successful runs / total runs: " << mNumSuccessfulRuns << " / " << mNumStartedRuns
67            << "\n";
68     stream << "- Total run duration: " << FormatDuration(mTotalRunDuration) << "\n";
69     stream << "- Average run duration: " << FormatDuration(mTotalRunDuration / mNumSuccessfulRuns)
70            << "\n";
71     stream << "- Running time fraction: "
72            << static_cast<double>(mTotalRunDuration.count()) /
73                       (mTimeSource->GetTime() - mStartTime).count()
74            << "\n";
75 
76     stream << "- Number of throttles:\n";
77     size_t totalNumThrottles = 0;
78     for (const auto &[throttleDecision, numThrottles] : mNumThrottles) {
79         stream << "  - " << ThrottleString(throttleDecision) << ": " << numThrottles << "\n";
80         totalNumThrottles += numThrottles;
81     }
82     stream << "  - Total: " << totalNumThrottles << "\n";
83 
84     stream << "- Time spent throttling:\n";
85     std::chrono::nanoseconds totalThrottleDuration;
86     for (const auto &[throttleDecision, throttleDuration] : mThrottleDurations) {
87         stream << "  - " << ThrottleString(throttleDecision) << ": "
88                << FormatDuration(throttleDuration) << "\n";
89         totalThrottleDuration += throttleDuration;
90     }
91     stream << "  - Total: " << FormatDuration(totalThrottleDuration) << "\n";
92 
93     stream << "- Missed deadlines per throttle:\n";
94     size_t totalNumDurations = 0;
95     size_t totalNumMissedDeadlines = 0;
96     for (const auto &[throttleDecision, numDurations] : mNumDurations) {
97         const size_t numMissedDeadlines = mNumMissedDeadlines.at(throttleDecision);
98         stream << "  - " << ThrottleString(throttleDecision) << ": " << numMissedDeadlines << " / "
99                << numDurations << " (" << static_cast<double>(numMissedDeadlines) / numDurations
100                << ")\n";
101         totalNumDurations += numDurations;
102         totalNumMissedDeadlines += numMissedDeadlines;
103     }
104     stream << "  - Total: " << totalNumMissedDeadlines << " / " << totalNumDurations << " ("
105            << static_cast<double>(totalNumMissedDeadlines) / totalNumDurations << ")\n";
106 }
107 
FormatDuration(std::chrono::nanoseconds duration)108 std::string AdaptiveCpuStats::FormatDuration(std::chrono::nanoseconds duration) {
109     double count = static_cast<double>(duration.count());
110     std::string suffix;
111     if (count < 1000.0) {
112         suffix = "ns";
113     } else if (count < 1000.0 * 1000) {
114         suffix = "us";
115         count /= 1000;
116     } else if (count < 1000.0 * 1000 * 100) {
117         suffix = "ms";
118         count /= 1000 * 1000;
119     } else {
120         suffix = "s";
121         count /= 1000 * 1000 * 1000;
122     }
123     return std::to_string(count) + suffix;
124 }
125 
126 }  // namespace pixel
127 }  // namespace impl
128 }  // namespace power
129 }  // namespace hardware
130 }  // namespace google
131 }  // namespace aidl
132