Improve physical geometry, fluid solvers, audio, and profiling

This commit is contained in:
max
2026-10-30 18:57:56 +01:00
parent bf8621ad39
commit eb2b6366c2
130 changed files with 14649 additions and 862 deletions

View File

@@ -0,0 +1,59 @@
#pragma once
#include <array>
#include <chrono>
#include <cstddef>
#include <algorithm>
#include <cstdint>
#include <string_view>
namespace fluidsim::port {
enum class ProfileStage : std::size_t { Total, Controls, Solver, Boundary, Pipe, Components, Audio, Count };
inline constexpr std::array<std::string_view,7> profile_stage_names{
"total", "controls", "solver", "boundary", "pipe", "components", "audio"};
struct ProfileTotals {
std::array<std::uint64_t,static_cast<std::size_t>(ProfileStage::Count)> nanoseconds{};
std::uint64_t sampled_steps{};
std::array<std::uint64_t,512> frame_histogram{};
};
inline double profile_percentile_ms(const ProfileTotals& totals,double quantile) {
if(!totals.sampled_steps) return 0;
const auto target=static_cast<std::uint64_t>(quantile*(totals.sampled_steps-1));
std::uint64_t count=0;
for(std::size_t i=0;i<totals.frame_histogram.size();++i) {
count+=totals.frame_histogram[i];
if(count>target) return (i+.5)*.001;
}
return .512;
}
class RuntimeProfiler {
public:
void enable(bool value) { enabled_=value; frame_=0; totals_={}; }
bool begin_step() { return enabled_ && (frame_++%2==0); }
void add(ProfileStage stage,std::uint64_t ns) { totals_.nanoseconds[static_cast<std::size_t>(stage)]+=ns; }
void finish_step(std::uint64_t elapsed_ns) {
++totals_.sampled_steps;
const auto bin=std::min<std::uint64_t>(elapsed_ns/1000,totals_.frame_histogram.size()-1);
++totals_.frame_histogram[bin];
}
double frame_percentile_ms(double quantile) const {
return profile_percentile_ms(totals_,quantile);
}
const ProfileTotals& totals() const { return totals_; }
bool enabled() const { return enabled_; }
private:
bool enabled_{};
std::uint64_t frame_{};
ProfileTotals totals_{};
};
class ProfileScope {
public:
ProfileScope(RuntimeProfiler* profiler,bool active,ProfileStage stage)
: profiler_(active?profiler:nullptr),stage_(stage),start_(profiler_?Clock::now():Clock::time_point{}) {}
~ProfileScope() { if(profiler_) profiler_->add(stage_,std::chrono::duration_cast<std::chrono::nanoseconds>(Clock::now()-start_).count()); }
std::uint64_t elapsed_ns() const {
return profiler_?std::chrono::duration_cast<std::chrono::nanoseconds>(Clock::now()-start_).count():0;
}
private:
using Clock=std::chrono::steady_clock;
RuntimeProfiler* profiler_{}; ProfileStage stage_{}; Clock::time_point start_{};
};
}