cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
point_utils.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm> // For std::generate_n, std::min, std::max
4#include <cmath> // For std::ceil
5#include <functional> // For std::ref if needed
6#include <future> // For std::future
7#include <iterator> // For std::back_inserter
8#include <random>
9#include <thread> // For std::thread::hardware_concurrency (used indirectly via default_pool)
10#include <vector>
11
12#include <cpp-toolbox/cpp-toolbox_export.hpp> // For CPP_TOOLBOX_EXPORT
13#include <cpp-toolbox/logger/thread_logger.hpp> // For LOG_* macros
14#include <cpp-toolbox/types/minmax.hpp> // Needs minmax_t definition (and includes parallel.hpp)
15#include <cpp-toolbox/types/point.hpp> // Needs point_t definition
16
17namespace toolbox::types
18{
19
43template<typename T>
44CPP_TOOLBOX_EXPORT auto generate_random_points(
45 const std::size_t& num_points, const minmax_t<point_t<T>>& minmax)
46 -> std::vector<point_t<T>>
47{
48 std::vector<point_t<T>> points;
49 points.reserve(num_points);
50
51 std::random_device rd;
52 std::mt19937 gen(rd());
53
54 std::uniform_real_distribution<T> dist_x(minmax.min.x, minmax.max.x);
55 std::uniform_real_distribution<T> dist_y(minmax.min.y, minmax.max.y);
56 std::uniform_real_distribution<T> dist_z(minmax.min.z, minmax.max.z);
57
58 std::generate_n(
59 std::back_inserter(points),
60 num_points,
61 [&]() { return point_t<T>(dist_x(gen), dist_y(gen), dist_z(gen)); });
62
63 return points;
64}
65
93template<typename T>
94CPP_TOOLBOX_EXPORT auto generate_random_points_parallel(
95 const std::size_t& num_points, const minmax_t<point_t<T>>& minmax)
96 -> std::vector<point_t<T>>
97{
98 LOG_DEBUG_S << "Generating " << num_points << " points in parallel.";
99 if (num_points == 0) {
100 return {};
101 }
102
103 // 预分配整个向量以避免并行任务中的调整大小 / Pre-allocate the entire vector
104 // to avoid resizing in parallel tasks
105 std::vector<point_t<T>> points(num_points);
106
107 // --- 使用线程池的并行执行逻辑 / Parallel execution logic using thread pool
108 // ---
110 const size_t num_threads = pool.get_thread_count();
111 const size_t hardware_threads =
112 std::max(1u, std::thread::hardware_concurrency());
113
114 // 定义分块策略(根据性能测试调整参数) / Define chunking strategy (adjust
115 // parameters based on performance testing)
116 const size_t min_chunk_size =
117 1024; // 每个任务的最小点数 / Minimum points per task
118 const size_t max_tasks = std::max(
119 static_cast<size_t>(1), std::max(num_threads, hardware_threads) * 4);
120 size_t chunk_size =
121 std::max(min_chunk_size,
122 static_cast<size_t>(
123 std::ceil(static_cast<double>(num_points) / max_tasks)));
124 size_t num_tasks = static_cast<size_t>(
125 std::ceil(static_cast<double>(num_points) / chunk_size));
126 if (num_tasks == 0 && num_points > 0)
127 num_tasks = 1; // 如果num_points > 0,确保至少有一个任务 / Ensure at least
128 // one task if num_points > 0
129
130 std::vector<std::future<void>> futures;
131 futures.reserve(num_tasks);
132
133 std::random_device rd;
134 unsigned int base_seed =
135 rd(); // 生成基础种子以确保线程间的可重现性 / Generate a base seed for
136 // reproducibility across threads
137
138 LOG_DEBUG_S << "Parallel generation using " << num_tasks
139 << " tasks with chunk size ~" << chunk_size;
140
141 size_t start_idx = 0;
142 for (size_t i = 0; i < num_tasks; ++i) {
143 size_t remaining_size = num_points - start_idx;
144 size_t current_chunk_actual_size = std::min(chunk_size, remaining_size);
145 if (current_chunk_actual_size == 0)
146 break; // 如果逻辑正确则不应发生 / Should not happen if logic is correct
147 size_t end_idx = start_idx + current_chunk_actual_size;
148
149 // 向线程池提交任务 / Submit task to the thread pool
150 futures.emplace_back(pool.submit(
151 // 通过值/引用捕获必要的变量 / Capture necessary variables by
152 // value/reference 'points'通过引用捕获 - 由于预分配和索引访问是安全的 /
153 // 'points' is captured by reference - safe due to pre-allocation and
154 // indexed access 'minmax'通过引用捕获(const) / 'minmax' captured by
155 // reference (const)
156 [start_idx, end_idx, &points, &minmax, base_seed, task_id = i]()
157 {
158 // --- 线程本地设置 / Thread-local setup ---
159 // 必须为每个任务/线程创建分布,因为它们可能保持状态 / Distributions
160 // must be created per task/thread as they might hold state
161 std::uniform_real_distribution<T> dist_x(minmax.min.x, minmax.max.x);
162 std::uniform_real_distribution<T> dist_y(minmax.min.y, minmax.max.y);
163 std::uniform_real_distribution<T> dist_z(minmax.min.z, minmax.max.z);
164
165 // 每个任务/线程的随机数生成器使用唯一种子 / Per-task/thread random
166 // number generator seeded uniquely 组合基础种子和任务ID提供变化 /
167 // Combining base seed and task ID provides variation
168 std::mt19937 gen(base_seed + static_cast<unsigned int>(task_id));
169
170 // 可选:记录任务开始(可能很详细) / Optional: Log task start (can be
171 // verbose) LOG_TRACE_S << "Task " << task_id << ": Generating points
172 // [" << start_idx << ", " << end_idx << ")";
173
174 // --- 为这个块生成点 / Generate points for this chunk ---
175 for (size_t k = start_idx; k < end_idx; ++k) {
176 // 直接赋值到预分配的向量元素 / Direct assignment to the
177 // pre-allocated vector element
178 points[k] = point_t<T>(dist_x(gen), dist_y(gen), dist_z(gen));
179 }
180 }));
181 start_idx = end_idx; // 移动到下一个块的开始 / Move to the next chunk start
182 }
183
184 // 等待所有任务完成并处理潜在的异常 / Wait for all tasks to complete and
185 // handle potential exceptions
186 try {
187 for (auto& fut : futures) {
188 fut.get(); // `.get()`等待并重新抛出任务中发生的异常 / `.get()` waits and
189 // rethrows exceptions if any occurred in the task
190 }
191 } catch (const std::exception& e) {
192 LOG_ERROR_S << "Exception during parallel point generation: " << e.what();
193 // 根据错误处理策略,可以清除点、重新抛出等 / Depending on error handling
194 // strategy, could clear points, rethrow, etc. 重新抛出通常是合适的 /
195 // Rethrowing is often appropriate
196 throw;
197 } catch (...) {
198 LOG_ERROR_S << "Unknown exception during parallel point generation.";
199 throw;
200 }
201
202 LOG_DEBUG_S << "Finished parallel generation of " << points.size()
203 << " points.";
204 return points;
205}
206
207} // namespace toolbox::types
#define LOG_DEBUG_S
DEBUG级别流式日志的宏 / Macro for DEBUG level stream logging.
Definition thread_logger.hpp:1329
#define LOG_ERROR_S
ERROR级别流式日志的宏 / Macro for ERROR level stream logging.
Definition thread_logger.hpp:1332
base::thread_pool_singleton_t & default_pool()
获取默认线程池实例/Get the default thread pool instance
Definition parallel.hpp:22
Definition minmax_impl.hpp:21
CPP_TOOLBOX_EXPORT auto generate_random_points_parallel(const std::size_t &num_points, const minmax_t< point_t< T > > &minmax) -> std::vector< point_t< T > >
在给定边界内并行生成随机点 / Generates random points within given bounds in parallel
Definition point_utils.hpp:94
CPP_TOOLBOX_EXPORT auto generate_random_points(const std::size_t &num_points, const minmax_t< point_t< T > > &minmax) -> std::vector< point_t< T > >
在给定边界内顺序生成随机点 / Generates random points within given bounds sequentially
Definition point_utils.hpp:44
存储和计算最小最大值的主模板类 / Primary template class for storing and calculating minimum and maximum values
Definition minmax.hpp:92
3D点/向量模板类 / A 3D point/vector template class
Definition point.hpp:48