/** * @file performance_test.cpp * @brief primitive_process 性能基准测试(架构适配版) * * 测试覆盖: * 1. SDF 评估性能 * 2. Descriptor 更新性能 * 3. AABB 计算性能 * 4. 大规模对象创建/销毁 * 5. 内存分配效率 * * @note 已适配新架构: * - new_primitive 需要 data_center 指针参数 * - 简化的销毁流程 */ #define _USE_MATH_DEFINES #include #include #include #include #include #include #include #include #include #include #include // ============================================================================ // 性能计时器 // ============================================================================ class ScopedTimer { public: explicit ScopedTimer(const char* name) : name_(name) { start_ = std::chrono::high_resolution_clock::now(); } ~ScopedTimer() { auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - start_); std::cout << " " << name_ << ": " << std::fixed << std::setprecision(2) << duration.count() / 1000.0 << " ms\n"; } private: const char* name_; std::chrono::high_resolution_clock::time_point start_; }; // ============================================================================ // 辅助函数(新架构简化版) // ============================================================================ void safe_destroy_primitive(primitive* ptr) { if (!ptr) return; ptr->destroy(); mi_free(ptr); } // ============================================================================ // 性能测试 1: SDF 评估 // ============================================================================ void benchmark_sdf_evaluation() { std::cout << "\n1. SDF Evaluation Performance\n"; primitive_data_center_t data_center; primitive* cyl = internal::new_primitive(PRIMITIVE_TYPE_CYLINDER, &data_center); auto subfaces = cyl->get_subfaces(); auto* cylinder_face = subfaces[0].get_ptr(); auto eval_sdf = internal::get_eval_sdf_ptr(surface_type::cylinder); constexpr int ITERATIONS = 1'000'000; Eigen::Vector3d test_point(1.5, 0.5, 0.3); { ScopedTimer timer("1M SDF evaluations"); double sum = 0.0; for (int i = 0; i < ITERATIONS; ++i) { sum += eval_sdf(make_pointer_wrapper(cylinder_face), test_point); } // 防止编译器优化掉循环 if (sum > 1e10) std::cout << " Result: " << sum << "\n"; } safe_destroy_primitive(cyl); } // ============================================================================ // 性能测试 2: Descriptor 更新 // ============================================================================ void benchmark_descriptor_update() { std::cout << "\n2. Descriptor Update Performance\n"; primitive_data_center_t data_center; primitive* cyl = internal::new_primitive(PRIMITIVE_TYPE_CYLINDER, &data_center); constexpr int ITERATIONS = 100'000; { ScopedTimer timer("100K descriptor updates"); for (int i = 0; i < ITERATIONS; ++i) { double r = 1.0 + i * 0.0001; double h = 2.0 + i * 0.0002; cylinder_descriptor_t desc{r, h}; cyl->update_geometry(&desc, 0); } } safe_destroy_primitive(cyl); } // ============================================================================ // 性能测试 3: AABB 计算 // ============================================================================ void benchmark_aabb_calculation() { std::cout << "\n3. AABB Calculation Performance\n"; primitive_data_center_t data_center; primitive* cyl = internal::new_primitive(PRIMITIVE_TYPE_CYLINDER, &data_center); constexpr int ITERATIONS = 1'000'000; { ScopedTimer timer("1M AABB calculations"); double sum = 0.0; for (int i = 0; i < ITERATIONS; ++i) { aabb_t aabb = cyl->fetch_aabb(); sum += aabb.volume(); } if (sum > 1e10) std::cout << " Result: " << sum << "\n"; } safe_destroy_primitive(cyl); } // ============================================================================ // 性能测试 4: 大规模对象创建/销毁(新架构适配) // ============================================================================ void benchmark_mass_creation() { std::cout << "\n4. Mass Object Creation/Destruction (New Architecture)\n"; primitive_data_center_t data_center; constexpr int COUNT = 10'000; { ScopedTimer timer("Create/destroy 10K primitives"); for (int i = 0; i < COUNT; ++i) { // 新架构:构造时传入 data_center 指针 primitive* cyl = internal::new_primitive(PRIMITIVE_TYPE_CYLINDER, &data_center); cylinder_descriptor_t desc{1.0 + i * 0.01, 2.0 + i * 0.02}; cyl->update_geometry(&desc, 0); safe_destroy_primitive(cyl); } } } // ============================================================================ // 性能测试 5: 批量对象管理(新架构适配) // ============================================================================ void benchmark_batch_management() { std::cout << "\n5. Batch Object Management (New Architecture)\n"; primitive_data_center_t data_center; constexpr int COUNT = 1'000; std::vector primitives; primitives.reserve(COUNT); { ScopedTimer timer("Create 1K primitives"); for (int i = 0; i < COUNT; ++i) { primitive* cyl = internal::new_primitive(PRIMITIVE_TYPE_CYLINDER, &data_center); primitives.push_back(cyl); } } { ScopedTimer timer("Update 1K descriptors"); for (int i = 0; i < COUNT; ++i) { cylinder_descriptor_t desc{1.0 + i * 0.1, 2.0 + i * 0.2}; primitives[i]->update_geometry(&desc, 0); } } { ScopedTimer timer("Calculate 1K AABBs"); double sum = 0.0; for (int i = 0; i < COUNT; ++i) { aabb_t aabb = primitives[i]->fetch_aabb(); sum += aabb.volume(); } std::cout << " Total volume: " << sum << "\n"; } { ScopedTimer timer("Destroy 1K primitives"); for (auto* p : primitives) { safe_destroy_primitive(p); } } } // ============================================================================ // 性能测试 6: 内存分配效率 // ============================================================================ void benchmark_memory_allocation() { std::cout << "\n6. Memory Allocation Efficiency\n"; constexpr int ITERATIONS = 100'000; { ScopedTimer timer("100K mimalloc allocations (64 bytes)"); std::vector ptrs; ptrs.reserve(ITERATIONS); for (int i = 0; i < ITERATIONS; ++i) { ptrs.push_back(mi_malloc(64)); } for (void* p : ptrs) { mi_free(p); } } { ScopedTimer timer("100K mimalloc allocations (1024 bytes)"); std::vector ptrs; ptrs.reserve(ITERATIONS); for (int i = 0; i < ITERATIONS; ++i) { ptrs.push_back(mi_malloc(1024)); } for (void* p : ptrs) { mi_free(p); } } } // ============================================================================ // 性能测试 7: 参数映射性能(新架构适配) // ============================================================================ void benchmark_parametrization() { std::cout << "\n7. Parametrization Performance (New Architecture)\n"; primitive_data_center_t data_center; primitive* cyl = internal::new_primitive(PRIMITIVE_TYPE_CYLINDER, &data_center); auto subfaces = cyl->get_subfaces(); auto* cylinder_face = subfaces[0].get_ptr(); auto map_param_to_point_with_weight = internal::get_map_param_to_point_with_weight_ptr(surface_type::cylinder); auto map_point_to_param = internal::get_map_point_to_param_ptr(surface_type::cylinder); constexpr int ITERATIONS = 1'000'000; { ScopedTimer timer("1M param->point conversions"); Eigen::Vector2d param(M_PI / 4, 0.5); Eigen::Vector3d sum = Eigen::Vector3d::Zero(); for (int i = 0; i < ITERATIONS; ++i) { // 使用结构化绑定从 std::tuple 中提取点坐标 auto [point_h, surface_jacobi, volume_jacobi] = map_param_to_point_with_weight(make_pointer_wrapper(cylinder_face), param); sum += point_h.head<3>(); } if (sum.norm() > 1e10) std::cout << " Result: " << sum.transpose() << "\n"; } { ScopedTimer timer("1M point->param conversions"); Eigen::Vector3d point(0.707, 0.707, 0.5); Eigen::Vector2d sum = Eigen::Vector2d::Zero(); for (int i = 0; i < ITERATIONS; ++i) { sum += map_point_to_param(make_pointer_wrapper(cylinder_face), point); } if (sum.norm() > 1e10) std::cout << " Result: " << sum.transpose() << "\n"; } safe_destroy_primitive(cyl); } // ============================================================================ // 主测试入口 // ============================================================================ int main() { SetConsoleOutputCP(CP_UTF8); std::cout << "╔══════════════════════════════════════════════╗\n"; std::cout << "║ PRIMITIVE_PROCESS PERFORMANCE BENCHMARK ║\n"; std::cout << "║ (New Architecture Adapted) ║\n"; std::cout << "╚══════════════════════════════════════════════╝\n"; std::cout << "mimalloc version: " << mi_version() << "\n\n"; // 获取初始内存状态 size_t initial_rss, initial_peak_rss; mi_process_info(nullptr, nullptr, nullptr, &initial_rss, &initial_peak_rss, nullptr, nullptr, nullptr); std::cout << "Initial RSS: " << (initial_rss / 1024) << " KB\n"; std::cout << "Initial Peak RSS: " << (initial_peak_rss / 1024) << " KB\n"; // 运行基准测试 benchmark_sdf_evaluation(); benchmark_descriptor_update(); benchmark_aabb_calculation(); benchmark_mass_creation(); benchmark_batch_management(); benchmark_memory_allocation(); benchmark_parametrization(); // 获取最终内存状态 size_t final_rss, final_peak_rss; mi_process_info(nullptr, nullptr, nullptr, &final_rss, &final_peak_rss, nullptr, nullptr, nullptr); std::cout << "\n╔══════════════════════════════════════════════╗\n"; std::cout << "║ MEMORY STATISTICS ║\n"; std::cout << "╚══════════════════════════════════════════════╝\n"; std::cout << "Final RSS: " << (final_rss / 1024) << " KB\n"; std::cout << "Peak RSS: " << (final_peak_rss / 1024) << " KB\n"; std::cout << "RSS Delta: " << ((final_rss - initial_rss) / 1024) << " KB\n"; std::cout << "\n╔══════════════════════════════════════════════╗\n"; std::cout << "║ ✓ BENCHMARK COMPLETED ║\n"; std::cout << "╚══════════════════════════════════════════════╝\n"; return 0; }