Temporary repository used to save branch code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

339 lines
12 KiB

/**
* @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 <windows.h>
#include <iostream>
#include <iomanip>
#include <chrono>
#include <vector>
#include <cmath>
#include <mimalloc.h>
#include <data/data_center.hpp>
#include <base/primitive.hpp>
#include <base/subface.hpp>
#include <primitive_descriptor.h>
// ============================================================================
// 性能计时器
// ============================================================================
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<std::chrono::microseconds>(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<primitive*> 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<void*> 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<void*> 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;
}