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
137 : {
138 150 : return static_cast<float64_t>(tick) / oneUsForTick_;
139 : }
140 :
141 : void InitProfileManager(const uint32_t deviceId);
142 :
143 : /**
144 : * init maker
145 : * @return NA
146 : */
147 : void InitMaker(const uint64_t schedTimes, const uint64_t schedDelay);
148 :
149 : void SetSrcQueueNum(const uint32_t srcQueueNum);
150 :
151 : void AddEnqueueNum();
152 :
153 : void AddDequeueNum();
154 :
155 : void AddCopyTotalCost(const uint64_t copyCost);
156 :
157 : void SetRelationCost(const uint64_t relationCost);
158 :
159 : void Setf2NFCost(const uint64_t f2NFCost);
160 :
161 : /**
162 : * Init marker for receive request event
163 : * @param schedTimes event sched times
164 : * @param schedDelay event sched delay
165 : */
166 : void InitMarkerForRecvReqEvent(const uint64_t schedTimes, const uint64_t schedDelay);
167 :
168 : /**
169 : * Init marker for receive completion event
170 : * @param schedTimes event sched times
171 : * @param schedDelay event sched delay
172 : */
173 : void InitMarkerForRecvCompEvent(const uint64_t schedTimes, const uint64_t schedDelay);
174 :
175 : /**
176 : * Init marker for send completion event
177 : * @param schedTimes event sched times
178 : * @param schedDelay event sched delay
179 : */
180 : void InitMarkerForSendCompEvent(const uint64_t schedTimes, const uint64_t schedDelay);
181 :
182 : /**
183 : * Do marker for recv request event
184 : * @param startTick start tick
185 : */
186 : void DoMarkerForRecvReqEvent(const uint64_t startTick);
187 :
188 : /**
189 : * Do marker for recv completion event
190 : * @param startTick start tick
191 : */
192 : void DoMarkerForRecvCompEvent(const uint64_t startTick);
193 :
194 : /**
195 : * Do marker for send completion event
196 : * @param startTick start tick
197 : */
198 : void DoMarkerForSendCompEvent(const uint64_t startTick);
199 :
200 : /**
201 : * Add HcclImprobe cost
202 : * @param cost api cost
203 : */
204 : void AddHcclImprobeCost(const uint64_t cost);
205 :
206 : /**
207 : * Add HcclGetCount cost
208 : * @param cost api cost
209 : */
210 : void AddHcclGetCountCost(const uint64_t cost);
211 :
212 : /**
213 : * Add HcclImrecv cost
214 : * @param cost api cost
215 : */
216 : void AddHcclImrecvCost(const uint64_t cost);
217 :
218 : /**
219 : * Add HcclTestSome cost
220 : * @param cost api cost
221 : * @param isRecvCompEvent is receive completion event
222 : */
223 : void AddHcclTestSomeCost(const uint64_t cost, const bool isRecvCompEvent);
224 :
225 : /**
226 : * Add request process completed cost
227 : * @param cost api cost
228 : * @param isRecvCompEvent is receive completion event
229 : * @return time cost (us)
230 : */
231 : const float64_t AddReqProcCompCost(const uint64_t cost, const bool isRecvCompEvent);
232 :
233 : /**
234 : * Add HcclIsend cost
235 : * @param cost api cost
236 : */
237 : void AddHcclIsendCost(const uint64_t cost);
238 :
239 : /**
240 : * Add mbuf alloc cost
241 : * @param cost api cost
242 : */
243 : void AddMbufAllocCost(const uint64_t cost);
244 :
245 : /**
246 : * Add enqueue cost for hccl
247 : * @param cost api cost
248 : */
249 : void AddHcclEnqueueCost(const uint64_t cost);
250 :
251 : /**
252 : * Add mbuf free cost
253 : * @param cost api cost
254 : */
255 : void AddMbufFreeCost(const uint64_t cost);
256 :
257 : /**
258 : * maker profile
259 : * @return NA
260 : */
261 : void DoMarker();
262 :
263 : /**
264 : * try to profile
265 : * @return NA
266 : */
267 : void TryMarker(const uint64_t startTick);
268 :
269 : void DoErrorLog() const;
270 :
271 : /**
272 : * process update profiling mode
273 : * @return BQS_STATUS_OK: success, other: failed.
274 : */
275 : BqsStatus UpdateProfilingMode(const ProfilingMode mode);
276 :
277 : /**
278 : * get profiling mode
279 : * @return ProfilingMode
280 : */
281 : ProfilingMode GetProfilingMode() const;
282 :
283 : /**
284 : * reset profiling
285 : */
286 : void ResetProfiling();
287 :
288 : void Uninit() const;
289 :
290 : private:
291 : ProfileManager();
292 :
293 : ~ProfileManager() = default;
294 :
295 : inline void GetAsmSysFreq(uint64_t &freq) const
296 : {
297 : #ifndef RUN_ON_X86
298 : asm volatile("mrs %0, CNTFRQ_EL0" : "=r"(freq) :);
299 : #endif
300 : }
301 :
302 : inline void GetAsmCpuTick(uint64_t &tick) const
303 : {
304 : #ifndef RUN_ON_X86
305 : asm volatile("mrs %0, CNTVCT_EL0" : "=r"(tick) :);
306 : #endif
307 : }
308 :
309 : #ifndef USE_PROFILER
310 : QueueScheduleTrack enqueEventTrack_;
311 : #else
312 : Hiva::QueueScheduleTrack enqueEventTrack_;
313 : #endif
314 :
315 : float64_t frequence_;
316 : uint64_t profThresholdTick_;
317 : uint64_t logThresholdTick_;
318 : float64_t oneUsForTick_;
319 : // profiling mode
320 : ProfilingMode profMode_;
321 : // schedule supplementary information
322 : SchedInfoTrack schedInfoTrack_;
323 : // receive request info track
324 : EnvelopeProbeTrack recvReqEventTrack_;
325 : // receive completion info track
326 : TestSomeInfoTrack recvCompEventTrack_;
327 : // send completion info track
328 : TestSomeInfoTrack sendCompEventTrack_;
329 : //need strict profiling threshold
330 : bool aicpuFeatureUseErrorLogThreshold_;
331 : // recv request event count
332 : std::atomic<uint64_t> recvReqEventCount_;
333 : // send completion event count
334 : std::atomic<uint64_t> sendCompEventCount_;
335 : // recv completion event count
336 : std::atomic<uint64_t> recvCompEventCount_;
337 : // enqueue event count
338 : std::atomic<uint64_t> enqueueEventCount_;
339 : };
340 : } // namespace bqs
341 : #endif // PROFILE_MANAGER_H
|