Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #ifndef PROFILE_MANAGER_H
12 : #define PROFILE_MANAGER_H
13 :
14 : #include <atomic>
15 : #include <cstdint>
16 : #include "queue_schedule/dgw_client.h"
17 : #include "common/bqs_log.h"
18 : #include "common/bqs_status.h"
19 : #ifndef USE_PROFILER
20 : #else
21 : #include "hiperf_common.h"
22 : #endif
23 :
24 : namespace bqs {
25 : #ifndef USE_PROFILER
26 : struct QueueScheduleTrackTag {
27 : uint64_t schedDelay;
28 : uint64_t startStamp;
29 : uint64_t schedTimes;
30 : uint32_t event;
31 : uint32_t state;
32 : uint32_t recordThreshold;
33 : uint64_t dequeueNum;
34 : uint64_t enqueueNum;
35 : uint64_t copyCost;
36 : uint32_t fullQueueNum;
37 : uint32_t srcQueueNum;
38 : uint64_t relationCost;
39 : uint64_t f2NFCost;
40 : uint64_t totalCost;
41 : };
42 : using QueueScheduleTrack = QueueScheduleTrackTag;
43 : #endif
44 :
45 : // supplementary information in schedule track, only called in ENQUEUE thread
46 : struct SchedInfoTrack {
47 : uint64_t hcclIsendNum;
48 : uint64_t totalHcclIsendCost;
49 : uint64_t maxHcclIsendCost;
50 : uint64_t hcclImrecvNum;
51 : uint64_t totalHcclImrecvCost;
52 : uint64_t maxHcclImrecvCost;
53 : uint64_t recvReqEventTotalDelay;
54 : uint64_t recvReqEventMaxDelay;
55 : uint64_t recvReqEventMinDelay;
56 : uint64_t recvCompEventTotalDelay;
57 : uint64_t recvCompEventMaxDelay;
58 : uint64_t recvCompEventMinDelay;
59 : uint64_t sendCompEventTotalDelay;
60 : uint64_t sendCompEventMaxDelay;
61 : uint64_t sendCompEventMinDelay;
62 : };
63 :
64 : // recv request info track, only called in RECEIVE_REQUEST_PROCESSED thread
65 : struct EnvelopeProbeTrack {
66 : uint64_t schedTimes; // event scheduled times
67 : uint64_t schedDelay; // event scheduled delay
68 : uint64_t hcclImprobeNum;
69 : uint64_t totalHcclImprobeCost;
70 : uint64_t maxHcclImprobeCost;
71 : uint64_t hcclGetCountNum;
72 : uint64_t totalHcclGetCountCost;
73 : uint64_t maxHcclGetCountCost;
74 : uint64_t hcclImrecvNum;
75 : uint64_t totalHcclImrecvCost;
76 : uint64_t maxHcclImrecvCost;
77 : uint64_t mbufAllocNum;
78 : uint64_t totalMbufAllocCost;
79 : uint64_t maxMbufAllocCost;
80 : };
81 :
82 : // test some info track, called in RECEIVE_COMPLETION or SEND_COMPLETION thread
83 : struct TestSomeInfoTrack {
84 : uint64_t schedTimes; // event scheduled times
85 : uint64_t schedDelay; // event scheduled delay
86 : uint64_t hcclTestSomeNum;
87 : uint64_t totalHcclTestSomeCost;
88 : uint64_t maxHcclTestSomeCost;
89 : uint64_t enqueueNum;
90 : uint64_t totalEnqueueCost;
91 : uint64_t maxEnqueueCost;
92 : uint64_t reqProcCompNum;
93 : uint64_t totalReqProcCompCost;
94 : uint64_t maxReqProcCompCost;
95 : uint64_t mbufFreeNum;
96 : uint64_t totalMbufFreeCost;
97 : uint64_t maxMbufFreeCost;
98 : };
99 :
100 : class ProfileManager {
101 : public:
102 : static ProfileManager& GetInstance(const uint32_t resIndex = 0U);
103 :
104 : ProfileManager(const ProfileManager&) = delete;
105 :
106 : ProfileManager(ProfileManager&&) = delete;
107 :
108 : ProfileManager& operator=(const ProfileManager&) = delete;
109 :
110 : ProfileManager& operator=(ProfileManager&&) = delete;
111 :
112 357 : inline uint64_t GetCpuTick() const
113 : {
114 357 : uint64_t tick = 0UL;
115 : #ifndef RUN_ON_X86
116 : GetAsmCpuTick(tick);
117 : #else
118 : struct timespec ts;
119 357 : clock_gettime(CLOCK_MONOTONIC, &ts);
120 357 : tick = (ts.tv_sec * 1000000UL + ts.tv_nsec / 1000UL);
121 : #endif
122 357 : return tick;
123 : };
124 :
125 18 : inline uint64_t GetSystemFreq() const
126 : {
127 18 : uint64_t freq = 1UL;
128 : #ifndef RUN_ON_X86
129 : GetAsmSysFreq(freq);
130 : #else
131 18 : freq = 1000000UL;
132 : #endif
133 18 : return freq;
134 : };
135 :
136 150 : inline float64_t GetTimeCost(const uint64_t tick) const { return static_cast<float64_t>(tick) / oneUsForTick_; }
137 :
138 : void InitProfileManager(const uint32_t deviceId);
139 :
140 : /**
141 : * init maker
142 : * @return NA
143 : */
144 : void InitMaker(const uint64_t schedTimes, const uint64_t schedDelay);
145 :
146 : void SetSrcQueueNum(const uint32_t srcQueueNum);
147 :
148 : void AddEnqueueNum();
149 :
150 : void AddDequeueNum();
151 :
152 : void AddCopyTotalCost(const uint64_t copyCost);
153 :
154 : void SetRelationCost(const uint64_t relationCost);
155 :
156 : void Setf2NFCost(const uint64_t f2NFCost);
157 :
158 : /**
159 : * Init marker for receive request event
160 : * @param schedTimes event sched times
161 : * @param schedDelay event sched delay
162 : */
163 : void InitMarkerForRecvReqEvent(const uint64_t schedTimes, const uint64_t schedDelay);
164 :
165 : /**
166 : * Init marker for receive completion event
167 : * @param schedTimes event sched times
168 : * @param schedDelay event sched delay
169 : */
170 : void InitMarkerForRecvCompEvent(const uint64_t schedTimes, const uint64_t schedDelay);
171 :
172 : /**
173 : * Init marker for send completion event
174 : * @param schedTimes event sched times
175 : * @param schedDelay event sched delay
176 : */
177 : void InitMarkerForSendCompEvent(const uint64_t schedTimes, const uint64_t schedDelay);
178 :
179 : /**
180 : * Do marker for recv request event
181 : * @param startTick start tick
182 : */
183 : void DoMarkerForRecvReqEvent(const uint64_t startTick);
184 :
185 : /**
186 : * Do marker for recv completion event
187 : * @param startTick start tick
188 : */
189 : void DoMarkerForRecvCompEvent(const uint64_t startTick);
190 :
191 : /**
192 : * Do marker for send completion event
193 : * @param startTick start tick
194 : */
195 : void DoMarkerForSendCompEvent(const uint64_t startTick);
196 :
197 : /**
198 : * Add HcclImprobe cost
199 : * @param cost api cost
200 : */
201 : void AddHcclImprobeCost(const uint64_t cost);
202 :
203 : /**
204 : * Add HcclGetCount cost
205 : * @param cost api cost
206 : */
207 : void AddHcclGetCountCost(const uint64_t cost);
208 :
209 : /**
210 : * Add HcclImrecv cost
211 : * @param cost api cost
212 : */
213 : void AddHcclImrecvCost(const uint64_t cost);
214 :
215 : /**
216 : * Add HcclTestSome cost
217 : * @param cost api cost
218 : * @param isRecvCompEvent is receive completion event
219 : */
220 : void AddHcclTestSomeCost(const uint64_t cost, const bool isRecvCompEvent);
221 :
222 : /**
223 : * Add request process completed cost
224 : * @param cost api cost
225 : * @param isRecvCompEvent is receive completion event
226 : * @return time cost (us)
227 : */
228 : const float64_t AddReqProcCompCost(const uint64_t cost, const bool isRecvCompEvent);
229 :
230 : /**
231 : * Add HcclIsend cost
232 : * @param cost api cost
233 : */
234 : void AddHcclIsendCost(const uint64_t cost);
235 :
236 : /**
237 : * Add mbuf alloc cost
238 : * @param cost api cost
239 : */
240 : void AddMbufAllocCost(const uint64_t cost);
241 :
242 : /**
243 : * Add enqueue cost for hccl
244 : * @param cost api cost
245 : */
246 : void AddHcclEnqueueCost(const uint64_t cost);
247 :
248 : /**
249 : * Add mbuf free cost
250 : * @param cost api cost
251 : */
252 : void AddMbufFreeCost(const uint64_t cost);
253 :
254 : /**
255 : * maker profile
256 : * @return NA
257 : */
258 : void DoMarker();
259 :
260 : /**
261 : * try to profile
262 : * @return NA
263 : */
264 : void TryMarker(const uint64_t startTick);
265 :
266 : void DoErrorLog() const;
267 :
268 : /**
269 : * process update profiling mode
270 : * @return BQS_STATUS_OK: success, other: failed.
271 : */
272 : BqsStatus UpdateProfilingMode(const ProfilingMode mode);
273 :
274 : /**
275 : * get profiling mode
276 : * @return ProfilingMode
277 : */
278 : ProfilingMode GetProfilingMode() const;
279 :
280 : /**
281 : * reset profiling
282 : */
283 : void ResetProfiling();
284 :
285 : void Uninit() const;
286 :
287 : private:
288 : ProfileManager();
289 :
290 : ~ProfileManager() = default;
291 :
292 : inline void GetAsmSysFreq(uint64_t& freq) const
293 : {
294 : #ifndef RUN_ON_X86
295 : asm volatile("mrs %0, CNTFRQ_EL0" : "=r"(freq) :);
296 : #endif
297 : }
298 :
299 : inline void GetAsmCpuTick(uint64_t& tick) const
300 : {
301 : #ifndef RUN_ON_X86
302 : asm volatile("mrs %0, CNTVCT_EL0" : "=r"(tick) :);
303 : #endif
304 : }
305 :
306 : #ifndef USE_PROFILER
307 : QueueScheduleTrack enqueEventTrack_;
308 : #else
309 : Hiva::QueueScheduleTrack enqueEventTrack_;
310 : #endif
311 :
312 : float64_t frequence_;
313 : uint64_t profThresholdTick_;
314 : uint64_t logThresholdTick_;
315 : float64_t oneUsForTick_;
316 : // profiling mode
317 : ProfilingMode profMode_;
318 : // schedule supplementary information
319 : SchedInfoTrack schedInfoTrack_;
320 : // receive request info track
321 : EnvelopeProbeTrack recvReqEventTrack_;
322 : // receive completion info track
323 : TestSomeInfoTrack recvCompEventTrack_;
324 : // send completion info track
325 : TestSomeInfoTrack sendCompEventTrack_;
326 : // need strict profiling threshold
327 : bool aicpuFeatureUseErrorLogThreshold_;
328 : // recv request event count
329 : std::atomic<uint64_t> recvReqEventCount_;
330 : // send completion event count
331 : std::atomic<uint64_t> sendCompEventCount_;
332 : // recv completion event count
333 : std::atomic<uint64_t> recvCompEventCount_;
334 : // enqueue event count
335 : std::atomic<uint64_t> enqueueEventCount_;
336 : };
337 : } // namespace bqs
338 : #endif // PROFILE_MANAGER_H
|