VLink 2.0.0
A high-performance communication middleware
载入中...
搜索中...
未找到
cpu_profiler.h
浏览该文件的文档.
1/*
2 * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 * Author: Thun Lu <thun.lu@zohomail.cn>
4 * Repo: https://github.com/thun-res/vlink
5 * _ __ __ _ __
6 * | | / / / / (_) ____ / /__
7 * | | / / / / / / / __ \ / //_/
8 * | |/ / / /___ / / / / / / / ,<
9 * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/**
25 * @file cpu_profiler.h
26 * @brief Per-instance CPU utilisation profiler gated by a global environment variable.
27 *
28 * @details
29 * @c CpuProfiler measures the fraction of wall-clock time that the CPU was actively
30 * executing work between paired @c begin() / @c end() calls. It uses two @c ElapsedTimer
31 * instances internally:
32 *
33 * - @c cpu_active_timer_ -- measures only active time (CPU time spent in the section).
34 * - @c cpu_timestamp_timer_ -- measures total elapsed wall-clock time since @c begin().
35 *
36 * The utilisation ratio is:
37 * @code
38 * utilisation (%) = (sum of active intervals / total elapsed time) * 100
39 * @endcode
40 *
41 * @par Global enable gate
42 * Profiling is gated by the environment variable @c VLINK_PROFILER_ENABLE.
43 * Set it to @c "1" to enable; @c "0" (default) to disable. The value is read once at
44 * first call to @c is_global_enabled() and cached for the process lifetime.
45 * @code
46 * export VLINK_PROFILER_ENABLE=1
47 * @endcode
48 *
49 * @par Typical usage
50 * @code
51 * vlink::CpuProfiler profiler;
52 *
53 * for (auto& item : work_items) {
54 * profiler.begin();
55 * process(item);
56 * profiler.end();
57 * }
58 *
59 * double pct = profiler.get(); // CPU utilisation since first begin()
60 * double reset_pct = profiler.restart(); // returns current value and resets
61 * @endcode
62 *
63 * @note
64 * - @c begin() and @c end() are guarded by an internal @c SpinLock and are safe to call
65 * from any thread, but each profiler instance measures a single logical stream of work.
66 * - If profiling is globally disabled, @c begin() / @c end() still execute but should be
67 * short-circuited by the caller using @c is_global_enabled() for maximum performance.
68 * - @c CpuProfilerGuard provides a convenient RAII wrapper that calls @c begin() and
69 * @c end() automatically.
70 */
71
72#pragma once
73
74#include <atomic>
75#include <cstdint>
76
77#include "./elapsed_timer.h"
78#include "./macros.h"
79#include "./spin_lock.h"
80
81namespace vlink {
82
83/**
84 * @class CpuProfiler
85 * @brief Tracks CPU active time as a percentage of total elapsed wall-clock time.
86 *
87 * @details
88 * Each @c begin() / @c end() pair contributes one active interval to the running total.
89 * @c get() returns the cumulative utilisation ratio; @c restart() returns the ratio and
90 * resets all accumulators.
91 *
92 * @note Copy and assignment are disabled. Instances should be owned by a single component.
93 */
95 public:
96 /**
97 * @brief Constructs a profiler with all accumulators initialised to zero.
98 */
99 CpuProfiler() noexcept;
100
101 /**
102 * @brief Destructor.
103 */
104 ~CpuProfiler() noexcept;
105
106 /**
107 * @brief Returns whether CPU profiling is globally enabled via environment variable.
108 *
109 * @details
110 * Reads @c VLINK_PROFILER_ENABLE on the first call and caches the result.
111 * Returns @c true if the variable is set to @c "1", @c false otherwise.
112 *
113 * @return @c true if profiling is enabled globally.
114 */
115 [[nodiscard]] static bool is_global_enabled() noexcept;
116
117 /**
118 * @brief Marks the start of an active CPU work section.
119 *
120 * @details
121 * Restarts the active-time timer. If this is the very first call, also starts the
122 * wall-clock timestamp timer used as the denominator in @c get().
123 * Safe to call multiple times; each call resets the active-timer baseline.
124 *
125 * @note This method acquires an internal @c SpinLock briefly.
126 */
127 void begin() noexcept;
128
129 /**
130 * @brief Marks the end of an active CPU work section and accumulates the elapsed time.
131 *
132 * @details
133 * Reads the active-time elapsed since the last @c begin() and adds it to the running
134 * total (@c total_active_). Negative elapsed values (e.g., clock skew) are ignored.
135 *
136 * @note This method acquires an internal @c SpinLock briefly.
137 */
138 void end() noexcept;
139
140 /**
141 * @brief Returns the current CPU utilisation ratio as a percentage.
142 *
143 * @details
144 * Computes: @c (total_active_ns / total_elapsed_ns) * 100.0
145 * Returns @c 0.0 if no time has elapsed since profiling started.
146 *
147 * @return CPU utilisation in the range [0.0, 100.0] (may exceed 100 on multi-core).
148 */
149 [[nodiscard]] double get() const noexcept;
150
151 /**
152 * @brief Returns the current utilisation and resets all accumulators to zero.
153 *
154 * @details
155 * The return value is identical to calling @c get() before the reset.
156 * After this call, @c get() returns @c 0.0 until the next @c begin() / @c end() pair.
157 *
158 * @note This method acquires an internal @c SpinLock briefly.
159 *
160 * @return CPU utilisation percentage accumulated since construction or the last @c restart().
161 */
162 double restart() noexcept;
163
164 private:
165 alignas(64) std::atomic<uint64_t> total_active_{0};
167 ElapsedTimer cpu_timestamp_timer_{ElapsedTimer::kCpuTimestamp, ElapsedTimer::kNano};
168 SpinLock spin_;
169
171};
172
173} // namespace vlink
High-resolution elapsed-time measurement with configurable clock source and precision.
Platform-independent macro definitions for the VLink library.
#define VLINK_EXPORT
定义 macros.h:85
#define VLINK_DISALLOW_COPY_AND_ASSIGN(classname)
Deletes the copy constructor and copy-assignment operator of classname.
定义 macros.h:184
STL namespace
Adaptive, cache-line-aligned spin lock and RAII guard.