1 /*
2  * Copyright (c) 2023 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 #ifndef FFRT_LOAD_PREDICTOR_H
17 #define FFRT_LOAD_PREDICTOR_H
18 
19 #include <array>
20 #include <algorithm>
21 
22 namespace ffrt {
23 template <typename T>
24 class LoadPredictor {
25 public:
26     virtual ~LoadPredictor() = default;
27 
GetPredictLoad()28     uint64_t GetPredictLoad() const
29     {
30         return static_cast<const T*>(this)->GetPredictLoadImpl();
31     }
32 
UpdateLoad(uint64_t load)33     void UpdateLoad(uint64_t load)
34     {
35         static_cast<T*>(this)->UpdateLoadImpl(load);
36     }
37 
Clear()38     void Clear()
39     {
40         static_cast<T*>(this)->ClearImpl();
41     }
42 };
43 
44 class SimpleLoadPredictor : public LoadPredictor<SimpleLoadPredictor> {
45     friend class LoadPredictor<SimpleLoadPredictor>;
46 
47 public:
SimpleLoadPredictor()48     SimpleLoadPredictor()
49     {
50         std::fill(loadHist.begin(), loadHist.end(), 0UL);
51     }
52 
53 private:
GetPredictLoadImpl()54     uint64_t GetPredictLoadImpl() const
55     {
56         return maxLoad;
57     }
58 
UpdateLoadImpl(uint64_t load)59     void UpdateLoadImpl(uint64_t load)
60     {
61         uint64_t sum = load;
62 
63         auto end = loadHist.rend() - 1;
64         for (auto begin = loadHist.rbegin(); begin < end; ++begin) {
65             *begin = *(begin + 1);
66             sum += *begin;
67         }
68         *end = load;
69 
70         maxLoad = std::max({ sum / HIST_SIZE, loadHist[0], loadHist[1] });
71     }
72 
ClearImpl()73     void ClearImpl()
74     {
75         maxLoad = 0;
76         std::fill(loadHist.begin(), loadHist.end(), 0UL);
77     }
78 
79     static constexpr int HIST_SIZE = 5;
80     std::array<uint64_t, HIST_SIZE> loadHist;
81 
82     uint64_t maxLoad = 0;
83 };
84 }; // namespace ffrt
85 
86 #endif