ParticleBox

C++17 | SDL2 | OpenMP | Apple SIMD MIT License
128
24
76

A high-performance C++ particle simulator leveraging multithreading (OpenMP & GCD), spatial partitioning (grid), SIMD (Apple Accelerate & auto-vectorization), and optimized memory patterns for real-time physics simulation.

Updated March 2025

Overview

ParticleBox is a performant C++ particle simulator designed to efficiently simulate the interactions of thousands of particles in real-time. It utilizes modern C++ features and platform-specific optimizations to achieve high frame rates, even with large particle counts.

Key performance techniques implemented in ParticleBox:

Technical Highlights

Background

Mathematical Foundation

ParticleBox simulates particle interactions using optimized numerical methods.

Collision Detection Mathematics

Collision detection between two particles (p1, p2) primarily uses squared distances to avoid expensive square root calculations in the inner loop. The squared distance \(d^2\) is calculated:

\[ d^2 = (p2.x - p1.x)^2 + (p2.y - p1.y)^2 \]

A collision is detected if \(d^2 < (r1 + r2)^2\), where \(r1\) and \(r2\) are the particle radii. When the actual distance or a normalized direction vector is required (e.g., for force calculation), the optimized Fast Inverse Square Root (fastInvSqrt) function is used to calculate \(1/\sqrt{d^2}\).

Force Calculation

A simple linear repulsion force is applied when particles overlap. The magnitude of the repulsion force \(F_r\) between overlapping particles is proportional to the overlap depth:

\[ \mathbf{F}_r = -\hat{\mathbf{n}} \cdot \text{repulsionStrength} \cdot \delta \]

Where \(\delta\) is the overlap distance \((r1 + r2) - d\), \(\text{repulsionStrength}\) is a constant factor (REPULSION_STRENGTH in physics.h), and \(\hat{\mathbf{n}}\) is the normalized direction vector from particle \(i\) to particle \(j\), calculated efficiently using fastInvSqrt. Force calculations leverage SIMD vector types (simd_float2) on Apple platforms.

Integration Method

The simulation uses a Semi-Implicit Euler integration method to update particle positions and velocities:

\[ \mathbf{v}_{t+\Delta t} = \mathbf{v}_t + (\mathbf{F}_t / m) \cdot \Delta t \] \[ \mathbf{p}_{t+\Delta t} = \mathbf{p}_t + \mathbf{v}_{t+\Delta t} \cdot \Delta t \]

Where \(\mathbf{p}\) is position, \(\mathbf{v}\) is velocity, \(\mathbf{F}\) is the net force, \(m\) is mass, and \(\Delta t\) is the time step. This method is straightforward to implement and computationally inexpensive.

Implementation

System Architecture

ParticleBox is structured into several key components:

Spatial Partitioning (Grid)

When enabled, the spatial partitioning system uses a uniform grid to optimize collision detection:

Multithreaded Physics Engine

The physics engine distributes computational work across available CPU cores:

SIMD Optimizations

Vector operations are accelerated using Single Instruction, Multiple Data (SIMD) techniques:

Memory Optimizations

Memory access and allocation patterns are optimized for performance:

Math Optimizations

Mathematical calculations are optimized for speed:

Performance Optimization

Multithreading Implementation

ParticleBox utilizes multi-core CPUs effectively through:

Memory Optimization Techniques

Memory performance is enhanced through:

Profiling-Driven Optimizations

Performance improvements were guided by analyzing bottlenecks. Key areas addressed include:

Technology Stack

C++ Logo
Fullscreen image