132 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2021 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #define LOG_TAG "powerhal-adaptivecpu"
 | |
| #define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
 | |
| 
 | |
| #include "AdaptiveCpuStats.h"
 | |
| 
 | |
| #include <utils/Trace.h>
 | |
| 
 | |
| #include "AdaptiveCpu.h"
 | |
| 
 | |
| using std::chrono_literals::operator""ns;
 | |
| 
 | |
| namespace aidl {
 | |
| namespace google {
 | |
| namespace hardware {
 | |
| namespace power {
 | |
| namespace impl {
 | |
| namespace pixel {
 | |
| 
 | |
| void AdaptiveCpuStats::RegisterStartRun() {
 | |
|     ATRACE_CALL();
 | |
|     mNumStartedRuns++;
 | |
|     mLastRunStartTime = mTimeSource->GetTime();
 | |
|     if (mStartTime == 0ns) {
 | |
|         mStartTime = mLastRunStartTime;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void AdaptiveCpuStats::RegisterSuccessfulRun(ThrottleDecision previousThrottleDecision,
 | |
|                                              ThrottleDecision throttleDecision,
 | |
|                                              WorkDurationFeatures workDurationFeatures,
 | |
|                                              const AdaptiveCpuConfig &config) {
 | |
|     ATRACE_CALL();
 | |
|     mNumSuccessfulRuns++;
 | |
|     mNumThrottles[throttleDecision]++;
 | |
|     const auto runSuccessTime = mTimeSource->GetTime();
 | |
|     mTotalRunDuration += runSuccessTime - mLastRunStartTime;
 | |
|     // Don't update previousThrottleDecision entries if we haven't run successfully before.
 | |
|     if (mLastRunSuccessTime != 0ns) {
 | |
|         mThrottleDurations[previousThrottleDecision] +=
 | |
|                 std::min(runSuccessTime - mLastRunSuccessTime,
 | |
|                          std::chrono::duration_cast<std::chrono::nanoseconds>(config.hintTimeout));
 | |
|         mNumDurations[previousThrottleDecision] += workDurationFeatures.numDurations;
 | |
|         mNumMissedDeadlines[previousThrottleDecision] += workDurationFeatures.numMissedDeadlines;
 | |
|     }
 | |
|     mLastRunSuccessTime = runSuccessTime;
 | |
| }
 | |
| 
 | |
| void AdaptiveCpuStats::DumpToStream(std::ostream &stream) const {
 | |
|     stream << "Stats:\n";
 | |
|     stream << "- Successful runs / total runs: " << mNumSuccessfulRuns << " / " << mNumStartedRuns
 | |
|            << "\n";
 | |
|     stream << "- Total run duration: " << FormatDuration(mTotalRunDuration) << "\n";
 | |
|     stream << "- Average run duration: " << FormatDuration(mTotalRunDuration / mNumSuccessfulRuns)
 | |
|            << "\n";
 | |
|     stream << "- Running time fraction: "
 | |
|            << static_cast<double>(mTotalRunDuration.count()) /
 | |
|                       (mTimeSource->GetTime() - mStartTime).count()
 | |
|            << "\n";
 | |
| 
 | |
|     stream << "- Number of throttles:\n";
 | |
|     size_t totalNumThrottles = 0;
 | |
|     for (const auto &[throttleDecision, numThrottles] : mNumThrottles) {
 | |
|         stream << "  - " << ThrottleString(throttleDecision) << ": " << numThrottles << "\n";
 | |
|         totalNumThrottles += numThrottles;
 | |
|     }
 | |
|     stream << "  - Total: " << totalNumThrottles << "\n";
 | |
| 
 | |
|     stream << "- Time spent throttling:\n";
 | |
|     std::chrono::nanoseconds totalThrottleDuration;
 | |
|     for (const auto &[throttleDecision, throttleDuration] : mThrottleDurations) {
 | |
|         stream << "  - " << ThrottleString(throttleDecision) << ": "
 | |
|                << FormatDuration(throttleDuration) << "\n";
 | |
|         totalThrottleDuration += throttleDuration;
 | |
|     }
 | |
|     stream << "  - Total: " << FormatDuration(totalThrottleDuration) << "\n";
 | |
| 
 | |
|     stream << "- Missed deadlines per throttle:\n";
 | |
|     size_t totalNumDurations = 0;
 | |
|     size_t totalNumMissedDeadlines = 0;
 | |
|     for (const auto &[throttleDecision, numDurations] : mNumDurations) {
 | |
|         const size_t numMissedDeadlines = mNumMissedDeadlines.at(throttleDecision);
 | |
|         stream << "  - " << ThrottleString(throttleDecision) << ": " << numMissedDeadlines << " / "
 | |
|                << numDurations << " (" << static_cast<double>(numMissedDeadlines) / numDurations
 | |
|                << ")\n";
 | |
|         totalNumDurations += numDurations;
 | |
|         totalNumMissedDeadlines += numMissedDeadlines;
 | |
|     }
 | |
|     stream << "  - Total: " << totalNumMissedDeadlines << " / " << totalNumDurations << " ("
 | |
|            << static_cast<double>(totalNumMissedDeadlines) / totalNumDurations << ")\n";
 | |
| }
 | |
| 
 | |
| std::string AdaptiveCpuStats::FormatDuration(std::chrono::nanoseconds duration) {
 | |
|     double count = static_cast<double>(duration.count());
 | |
|     std::string suffix;
 | |
|     if (count < 1000.0) {
 | |
|         suffix = "ns";
 | |
|     } else if (count < 1000.0 * 1000) {
 | |
|         suffix = "us";
 | |
|         count /= 1000;
 | |
|     } else if (count < 1000.0 * 1000 * 100) {
 | |
|         suffix = "ms";
 | |
|         count /= 1000 * 1000;
 | |
|     } else {
 | |
|         suffix = "s";
 | |
|         count /= 1000 * 1000 * 1000;
 | |
|     }
 | |
|     return std::to_string(count) + suffix;
 | |
| }
 | |
| 
 | |
| }  // namespace pixel
 | |
| }  // namespace impl
 | |
| }  // namespace power
 | |
| }  // namespace hardware
 | |
| }  // namespace google
 | |
| }  // namespace aidl
 |