Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
bottleneck_report.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
12#pragma once
13
14#include <cstddef>
15#include <iomanip>
16#include <sstream>
17#include <string>
18#include <vector>
19
21{
41
47 [[nodiscard]] inline auto bottleneck_type_to_string(bottleneck_type type) -> std::string
48 {
49 switch (type)
50 {
51 case bottleneck_type::none: return "none";
52 case bottleneck_type::queue_full: return "queue_full";
53 case bottleneck_type::slow_consumer: return "slow_consumer";
54 case bottleneck_type::worker_starvation: return "worker_starvation";
55 case bottleneck_type::lock_contention: return "lock_contention";
56 case bottleneck_type::uneven_distribution: return "uneven_distribution";
57 case bottleneck_type::memory_pressure: return "memory_pressure";
58 default: return "unknown";
59 }
60 }
61
92 {
96 bool has_bottleneck{false};
97
103 std::string description;
104
109
110 // =========================================================================
111 // Supporting Metrics
112 // =========================================================================
113
120 double queue_saturation{0.0};
121
127 double avg_wait_time_ms{0.0};
128
135
142
149
155 std::uint64_t jobs_rejected{0};
156
160 std::size_t queue_depth{0};
161
165 std::size_t idle_workers{0};
166
170 std::size_t total_workers{0};
171
172 // =========================================================================
173 // Recommendations
174 // =========================================================================
175
181 std::vector<std::string> recommendations;
182
183 // =========================================================================
184 // Computed Properties
185 // =========================================================================
186
191 [[nodiscard]] auto severity() const -> int
192 {
193 if (!has_bottleneck)
194 {
195 return 0;
196 }
197
198 // Critical: queue full or severe worker starvation
199 if (queue_saturation > 0.95 || worker_utilization > 0.98)
200 {
201 return 3;
202 }
203
204 // High: approaching capacity
205 if (queue_saturation > 0.8 || worker_utilization > 0.9)
206 {
207 return 2;
208 }
209
210 // Medium: noticeable but not urgent
211 return 1;
212 }
213
218 [[nodiscard]] auto severity_string() const -> std::string
219 {
220 switch (severity())
221 {
222 case 0: return "none";
223 case 1: return "low";
224 case 2: return "medium";
225 case 3: return "critical";
226 default: return "unknown";
227 }
228 }
229
234 [[nodiscard]] auto requires_immediate_action() const -> bool
235 {
236 return severity() >= 3;
237 }
238
265 [[nodiscard]] auto to_json() const -> std::string
266 {
267 std::ostringstream oss;
268 oss << "{\n";
269 oss << " \"has_bottleneck\": " << (has_bottleneck ? "true" : "false") << ",\n";
270 oss << " \"type\": \"" << bottleneck_type_to_string(type) << "\",\n";
271 oss << " \"severity\": \"" << severity_string() << "\",\n";
272 oss << " \"description\": \"" << description << "\",\n";
273
274 // Metrics
275 oss << " \"metrics\": {\n";
276 oss << std::fixed << std::setprecision(4);
277 oss << " \"queue_saturation\": " << queue_saturation << ",\n";
278 oss << std::setprecision(3);
279 oss << " \"avg_wait_time_ms\": " << avg_wait_time_ms << ",\n";
280 oss << std::setprecision(4);
281 oss << " \"worker_utilization\": " << worker_utilization << ",\n";
282 oss << " \"utilization_variance\": " << utilization_variance << ",\n";
283 oss << " \"estimated_backlog_time_ms\": " << estimated_backlog_time_ms << ",\n";
284 oss << " \"queue_depth\": " << queue_depth << ",\n";
285 oss << " \"idle_workers\": " << idle_workers << ",\n";
286 oss << " \"total_workers\": " << total_workers << ",\n";
287 oss << " \"jobs_rejected\": " << jobs_rejected << "\n";
288 oss << " },\n";
289
290 // Recommendations
291 oss << " \"recommendations\": [";
292 for (std::size_t i = 0; i < recommendations.size(); ++i)
293 {
294 oss << "\n \"" << recommendations[i] << "\"";
295 if (i < recommendations.size() - 1)
296 {
297 oss << ",";
298 }
299 }
300 if (!recommendations.empty())
301 {
302 oss << "\n ";
303 }
304 oss << "]\n";
305
306 oss << "}";
307 return oss.str();
308 }
309
333 [[nodiscard]] auto to_string() const -> std::string
334 {
335 std::ostringstream oss;
336
337 oss << "=== Bottleneck Report ===\n";
338 if (has_bottleneck)
339 {
340 oss << "Status: DETECTED (" << severity_string() << " severity)\n";
341 oss << "Type: " << bottleneck_type_to_string(type) << "\n";
342 oss << "Description: " << description << "\n\n";
343 }
344 else
345 {
346 oss << "Status: No bottleneck detected\n\n";
347 }
348
349 // Metrics
350 oss << "Metrics:\n";
351 oss << std::fixed;
352 oss << " Queue: " << queue_depth << " items ("
353 << std::setprecision(1) << (queue_saturation * 100.0) << "% saturated)\n";
354 oss << " Workers: " << (total_workers - idle_workers) << "/" << total_workers
355 << " active (" << idle_workers << " idle)\n";
356 oss << " Utilization: " << std::setprecision(1) << (worker_utilization * 100.0)
357 << "% (variance: " << std::setprecision(4) << utilization_variance << ")\n";
358 oss << " Wait time: " << std::setprecision(3) << avg_wait_time_ms << "ms avg\n";
359 oss << " Backlog: ~" << estimated_backlog_time_ms << "ms to clear\n";
360
361 if (jobs_rejected > 0)
362 {
363 oss << " Jobs rejected: " << jobs_rejected << "\n";
364 }
365
366 // Recommendations
367 if (!recommendations.empty())
368 {
369 oss << "\nRecommendations:\n";
370 for (const auto& rec : recommendations)
371 {
372 oss << " - " << rec << "\n";
373 }
374 }
375
376 return oss.str();
377 }
378 };
379
380} // namespace kcenon::thread::diagnostics
bottleneck_type
Type of bottleneck detected in the thread pool.
@ slow_consumer
Workers can't keep up with job submission rate.
@ lock_contention
High mutex wait times affecting throughput.
@ worker_starvation
Not enough workers for the workload.
@ memory_pressure
Excessive memory allocations causing slowdown.
@ uneven_distribution
Work is not evenly distributed (work stealing needed)
auto bottleneck_type_to_string(bottleneck_type type) -> std::string
Converts bottleneck_type to human-readable string.
STL namespace.
Analysis report of bottlenecks in the thread pool.
bottleneck_type type
Type of bottleneck detected.
double avg_wait_time_ms
Average wait time in milliseconds.
std::vector< std::string > recommendations
Actionable recommendations to resolve the bottleneck.
std::string description
Human-readable description of the bottleneck.
double utilization_variance
Variance in worker utilization.
auto to_string() const -> std::string
Converts the bottleneck report to a human-readable string.
auto requires_immediate_action() const -> bool
Checks if immediate action is required.
bool has_bottleneck
Whether a bottleneck was detected.
std::uint64_t jobs_rejected
Jobs rejected due to queue full.
std::size_t estimated_backlog_time_ms
Estimated time to process the current backlog.
auto severity() const -> int
Gets the severity level of the bottleneck.
std::size_t idle_workers
Number of idle workers.
auto severity_string() const -> std::string
Gets severity as a string.
std::size_t total_workers
Total number of workers.
auto to_json() const -> std::string
Converts the bottleneck report to a JSON string.
double worker_utilization
Average worker utilization.