Performance¶
Performance is a critical design consideration for Astrea, as aerospace applications often require real-time computation or processing of large datasets. This document outlines Astrea's performance architecture, optimization strategies, and benchmarking methodologies.
Performance Goals¶
Target Performance Characteristics¶
| Metric | Target | Measurement |
|---|---|---|
| Computational Overhead | ≤ 5% vs. hand-optimized C | Micro-benchmarks |
| Memory Overhead | Zero for abstractions | Static analysis |
| Compile-time Performance | < 10s for full rebuild | CI measurements |
| Cache Efficiency | > 95% L1 cache hit rate | Performance profiling |
| Vector Utilization | SIMD usage where applicable | Compiler analysis |
Performance Principles¶
- Zero-Cost Abstractions: High-level features compile to optimal machine code
- Compile-Time Computation: Move calculations from runtime to compile-time
- Cache-Friendly Design: Data structures optimized for memory access patterns
- SIMD Optimization: Leverage vector instructions for bulk operations
- Minimal Allocations: Prefer stack allocation and avoid unnecessary heap usage
Optimization Strategies¶
Compile-Time Optimization¶
Template Metaprogramming¶
// Coordinate transformation matrices computed at compile-time
template<typename FromFrame, typename ToFrame>
consteval auto transformation_matrix() {
if constexpr (std::is_same_v<FromFrame, ToFrame>) {
return math::Matrix3::identity();
} else if constexpr (is_constant_rotation_v<FromFrame, ToFrame>) {
return precomputed_rotation<FromFrame, ToFrame>();
} else {
// Runtime computation required
return std::nullopt;
}
}
// Usage - matrix computed at compile-time when possible
auto transform_position(const Position<ICRF>& pos) {
constexpr auto matrix = transformation_matrix<ICRF, J2000>();
if constexpr (matrix.has_value()) {
return matrix.value() * pos.vector(); // Compile-time matrix
} else {
return compute_runtime_transform<ICRF, J2000>(pos);
}
}
Constant Expression Evaluation¶
// Physical constants computed at compile-time
namespace constants {
constexpr auto earth_mu = 398600.4418 * units::km3_per_s2;
constexpr auto earth_radius = 6378.137 * units::km;
constexpr auto earth_j2 = 1.08262668e-3;
// Derived constants computed at compile-time
constexpr auto earth_angular_velocity = [] {
constexpr auto sidereal_day = 86164.0905 * units::second;
return 2.0 * std::numbers::pi * units::radian / sidereal_day;
}();
}
Memory Layout Optimization¶
Structure of Arrays (SoA) Pattern¶
// Optimized for bulk operations and SIMD
template<std::size_t N>
class StateVector {
// Separate arrays for each component (SoA)
std::array<double, N> x_, y_, z_; // Positions
std::array<double, N> vx_, vy_, vz_; // Velocities
std::array<double, N> epochs_; // Time stamps
public:
// SIMD-friendly bulk propagation
void propagate_kepler(double dt) {
// Vectorized operations on entire arrays
#pragma omp simd
for (std::size_t i = 0; i < N; ++i) {
// Kepler propagation for all states simultaneously
auto [new_x, new_y, new_z, new_vx, new_vy, new_vz] =
kepler_step(x_[i], y_[i], z_[i], vx_[i], vy_[i], vz_[i], dt);
x_[i] = new_x; y_[i] = new_y; z_[i] = new_z;
vx_[i] = new_vx; vy_[i] = new_vy; vz_[i] = new_vz;
epochs_[i] += dt;
}
}
};
Benchmarking and Profiling¶
Micro-Benchmarks¶
// Google Benchmark integration for performance testing
#include <benchmark/benchmark.h>
// Benchmark coordinate transformation performance
static void BenchmarkFrameTransform(benchmark::State& state) {
auto position = Position<ICRF>{Vector3{1000.0, 2000.0, 3000.0} * units::km};
auto epoch = EpochTT{1000.0 * units::julian_day};
for (auto _ : state) {
auto transformed = transform_position<ICRF, ITRF>(position, epoch);
benchmark::DoNotOptimize(transformed);
}
}
REGISTER_BENCHMARK(BenchmarkFrameTransform);
// Benchmark propagation performance
static void BenchmarkKeplerPropagation(benchmark::State& state) {
auto initial_state = KeplerianState{/* ... */};
auto dt = 60.0 * units::second;
for (auto _ : state) {
auto final_state = propagate_kepler(initial_state, dt);
benchmark::DoNotOptimize(final_state);
}
}
REGISTER_BENCHMARK(BenchmarkKeplerPropagation);
Astrea's performance architecture demonstrates that safety and performance are not mutually exclusive - through careful design and modern C++ techniques, we achieve both compile-time safety guarantees and runtime performance matching hand-optimized implementations.