• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "libpandabase/taskmanager/utils/task_time_stats.h"
17 #include "libpandabase/utils/time.h"
18 
19 #include <sstream>
20 #include <numeric>
21 #include <cmath>
22 #include <ostream>
23 
24 namespace ark::taskmanager {
25 
StringToTaskTimeStats(std::string_view str)26 TaskTimeStatsType StringToTaskTimeStats(std::string_view str)
27 {
28     if (str == "no-task-stats") {
29         return TaskTimeStatsType::NO_STATISTICS;
30     }
31     if (str == "light-task-stats") {
32         return TaskTimeStatsType::LIGHT_STATISTICS;
33     }
34     UNREACHABLE();
35 }
36 
operator <<(std::ostream & os,TaskTimeStatsType type)37 std::ostream &operator<<(std::ostream &os, TaskTimeStatsType type)
38 {
39     switch (type) {
40         case TaskTimeStatsType::NO_STATISTICS:
41             os << "TaskTimeStatsType::NO_STATISTICS";
42             break;
43         case TaskTimeStatsType::LIGHT_STATISTICS:
44             os << "TaskTimeStatsType::LIGHT_STATISTICS";
45             break;
46         default:
47             UNREACHABLE();
48             break;
49     }
50     return os;
51 }
52 
53 thread_local TaskTimeStatsBase::ContainerId TaskTimeStatsBase::containerId_ = TaskTimeStatsBase::DEFAULT_CONTAINER_ID;
54 
RegisterWorkerThread()55 void TaskTimeStatsBase::RegisterWorkerThread()
56 {
57     // Atomic with acq_rel order reason: fetch_add operation should be sync with calls from other threads
58     size_t registerNumber = countOfRegisteredWorkers_.fetch_add(1, std::memory_order_acq_rel);
59     containerId_ = registerNumber + 1U;
60 }
61 
62 namespace internal {
63 
LightTaskTimeTimeStats(size_t countOfWorkers)64 LightTaskTimeTimeStats::LightTaskTimeTimeStats(size_t countOfWorkers)
65     : statisticsContainerPerThread_(countOfWorkers + 1U)
66 {
67     for (auto &statisticsContainer : statisticsContainerPerThread_) {
68         for (size_t i = 0; i < STATISTICS_CONTAINER_SIZE; i++) {
69             statisticsContainer[i] = MeanTimeStats();
70         }
71     }
72 }
73 
CollectLifeAndExecutionTimes(TaskProperties prop,uint64_t lifeTime,uint64_t executionTime)74 void LightTaskTimeTimeStats::CollectLifeAndExecutionTimes(TaskProperties prop, uint64_t lifeTime,
75                                                           uint64_t executionTime)
76 {
77     auto propHash = TaskProperties::Hash()(prop);
78     auto &meanTimeStats = statisticsContainerPerThread_[containerId_][propHash];
79 
80     meanTimeStats.sumExecutionTime += executionTime;
81     meanTimeStats.sumLifeTime += lifeTime;
82 
83     meanTimeStats.maxExecutionTime = std::max(executionTime, meanTimeStats.maxExecutionTime);
84     meanTimeStats.maxLifeTime = std::max(lifeTime, meanTimeStats.maxLifeTime);
85 
86     ASSERT(meanTimeStats.sumLifeTime >= meanTimeStats.sumExecutionTime);
87 
88     meanTimeStats.countOfTasks++;
89 }
90 
GetTaskStatistics()91 std::vector<std::string> LightTaskTimeTimeStats::GetTaskStatistics()
92 {
93     std::vector<std::string> resultData;
94     for (auto prop : GetAllTaskProperties()) {
95         if (GetCountOfTasksWithProperties(prop) == 0) {
96             continue;
97         }
98         resultData.push_back(GetStatisticsForProperties(prop));
99     }
100     return resultData;
101 }
102 
GetAllTaskProperties()103 std::vector<TaskProperties> LightTaskTimeTimeStats::GetAllTaskProperties()
104 {
105     std::vector<TaskProperties> allTaskProperties;
106     for (TaskType taskType : ALL_TASK_TYPES) {
107         for (VMType vmType : ALL_VM_TYPES) {
108             for (TaskExecutionMode executionMode : ALL_TASK_EXECUTION_MODES) {
109                 allTaskProperties.emplace_back(taskType, vmType, executionMode);
110             }
111         }
112     }
113     return allTaskProperties;
114 }
115 
GetStatisticsForProperties(TaskProperties prop)116 std::string LightTaskTimeTimeStats::GetStatisticsForProperties(TaskProperties prop)
117 {
118     std::stringstream stream;
119     auto propHash = TaskProperties::Hash()(prop);
120     uint64_t sumLifeTime = 0;
121     uint64_t sumExecutionTime = 0;
122     uint64_t maxLifeTime = 0;
123     uint64_t maxExecutionTime = 0;
124     size_t sumTaskCount = 0;
125     for (const auto &statisticsContainer : statisticsContainerPerThread_) {
126         const auto &meanStatistics = statisticsContainer[propHash];
127         sumLifeTime += meanStatistics.sumLifeTime;
128         sumExecutionTime += meanStatistics.sumExecutionTime;
129 
130         maxLifeTime = std::max(meanStatistics.maxLifeTime, maxLifeTime);
131         maxExecutionTime = std::max(meanStatistics.maxExecutionTime, maxExecutionTime);
132 
133         sumTaskCount += meanStatistics.countOfTasks;
134     }
135     auto meanLifeTime = static_cast<double>(sumLifeTime) / sumTaskCount;
136     auto meanExecutionTime = static_cast<double>(sumExecutionTime) / sumTaskCount;
137     stream << "Task " << prop << ": mean life time: " << meanLifeTime << "us; max life time: " << maxLifeTime
138            << "us; mean execution time: " << meanExecutionTime << "us; "
139            << "max execution time: " << maxExecutionTime << "us; count of tasks: " << sumTaskCount << ";";
140     return stream.str();
141 }
142 
GetCountOfTasksWithProperties(TaskProperties prop)143 size_t LightTaskTimeTimeStats::GetCountOfTasksWithProperties(TaskProperties prop)
144 {
145     auto propHash = TaskProperties::Hash()(prop);
146     size_t sumTaskCount = 0;
147     for (const auto &statisticsContainer : statisticsContainerPerThread_) {
148         const auto &meanStatistics = statisticsContainer[propHash];
149         sumTaskCount += meanStatistics.countOfTasks;
150     }
151     return sumTaskCount;
152 }
153 
154 }  // namespace internal
155 
156 }  // namespace ark::taskmanager