POSIX Shared Memory Data Structures 1.0
High-performance lock-free data structures for inter-process communication
Loading...
Searching...
No Matches
simulation_patterns.cpp
Go to the documentation of this file.
1#include <iostream>
2#include <random>
3#include <chrono>
4#include <thread>
5#include "posix_shm.h"
6#include "shm_object_pool.h"
7#include "shm_ring_buffer.h"
8#include "shm_atomic.h"
9#include "shm_array.h"
10
11// Example: High-performance particle simulation using shared memory
12
13struct Particle {
14 float x, y, z;
15 float vx, vy, vz;
16 float lifetime;
17 uint32_t type;
18};
19
21 uint64_t timestamp;
23 float pressure;
24 float humidity;
25};
26
28 std::cout << "\n=== Particle Simulation with Object Pool ===\n";
29
30 posix_shm shm("particle_sim", 100 * 1024 * 1024); // 100MB
31
32 // Object pool for dynamic particle allocation
33 constexpr size_t MAX_PARTICLES = 10000;
34 shm_object_pool<Particle> particles(shm, "particles", MAX_PARTICLES);
35
36 // Statistics
37 shm_atomic_uint64 total_spawned(shm, "total_spawned", 0);
38 shm_atomic_uint64 total_destroyed(shm, "total_destroyed", 0);
39
40 std::cout << "Pool capacity: " << particles.capacity() << " particles\n";
41
42 // Spawn some particles
43 std::vector<uint32_t> handles;
44 for (int i = 0; i < 100; ++i) {
45 auto h = particles.acquire_construct();
46 if (h.has_value()) {
47 auto& p = particles[*h];
48 p.x = i * 0.1f;
49 p.y = i * 0.2f;
50 p.z = 0.0f;
51 p.lifetime = 10.0f;
52 handles.push_back(*h);
53 total_spawned++;
54 }
55 }
56
57 std::cout << "Spawned " << handles.size() << " particles\n";
58 std::cout << "Pool usage: " << particles.num_allocated()
59 << "/" << particles.capacity() << "\n";
60
61 // Simulate one frame - update particles
62 for (auto h : handles) {
63 auto& p = particles[h];
64 p.x += p.vx * 0.016f; // 60 FPS timestep
65 p.y += p.vy * 0.016f;
66 p.lifetime -= 0.016f;
67 }
68
69 // Destroy some particles
70 for (size_t i = 0; i < handles.size() / 2; ++i) {
71 particles.release(handles[i]);
72 total_destroyed++;
73 }
74
75 std::cout << "After destroying half:\n";
76 std::cout << "Pool usage: " << particles.num_allocated()
77 << "/" << particles.capacity() << "\n";
78 std::cout << "Total spawned: " << total_spawned.load() << "\n";
79 std::cout << "Total destroyed: " << total_destroyed.load() << "\n";
80}
81
83 std::cout << "\n=== Sensor Data Streaming with Ring Buffer ===\n";
84
85 posix_shm shm("sensor_stream", 10 * 1024 * 1024);
86
87 // Ring buffer for continuous sensor data
88 constexpr size_t BUFFER_SIZE = 1000;
89 shm_ring_buffer<SensorReading> sensor_buffer(shm, "sensors", BUFFER_SIZE);
90
91 // Generate some sensor data
92 std::random_device rd;
93 std::mt19937 gen(rd());
94 std::uniform_real_distribution<> temp_dist(20.0, 30.0);
95 std::uniform_real_distribution<> pressure_dist(1000.0, 1020.0);
96
97 auto now = std::chrono::system_clock::now();
98
99 // Push sensor readings
100 for (int i = 0; i < 50; ++i) {
101 SensorReading reading{
102 .timestamp = std::chrono::duration_cast<std::chrono::microseconds>(
103 now.time_since_epoch()).count() + i * 1000,
104 .temperature = static_cast<float>(temp_dist(gen)),
105 .pressure = static_cast<float>(pressure_dist(gen)),
106 .humidity = 45.0f + i * 0.1f
107 };
108
109 if (!sensor_buffer.push(reading)) {
110 std::cout << "Buffer full at " << i << " readings\n";
111 break;
112 }
113 }
114
115 std::cout << "Buffer contains " << sensor_buffer.size() << " readings\n";
116 std::cout << "Total written: " << sensor_buffer.total_written() << "\n";
117
118 // Get last 5 readings (most recent data)
119 SensorReading last_readings[5];
120 size_t got = sensor_buffer.get_last_n(5, last_readings);
121 std::cout << "\nLast " << got << " readings:\n";
122 for (size_t i = 0; i < got; ++i) {
123 std::cout << " T=" << last_readings[i].temperature
124 << "°C, P=" << last_readings[i].pressure << " hPa\n";
125 }
126
127 // Bulk read for processing
128 SensorReading batch[10];
129 size_t read = sensor_buffer.pop_bulk(batch);
130 std::cout << "\nProcessed " << read << " readings in batch\n";
131 std::cout << "Buffer now contains " << sensor_buffer.size() << " readings\n";
132}
133
135 std::cout << "\n=== Grid-based Simulation ===\n";
136
137 posix_shm shm("grid_sim", 50 * 1024 * 1024);
138
139 // Fixed grid for spatial data (e.g., fluid simulation, cellular automata)
140 constexpr size_t GRID_SIZE = 256 * 256;
141
142 struct Cell {
143 float density;
144 float velocity_x;
145 float velocity_y;
146 uint8_t type;
147 uint8_t flags;
148 uint16_t metadata;
149 };
150
151 // Two grids for double buffering
152 shm_array<Cell> grid_current(shm, "grid_current", GRID_SIZE);
153 shm_array<Cell> grid_next(shm, "grid_next", GRID_SIZE);
154
155 // Simulation step counter
156 shm_atomic_uint64 step_counter(shm, "step", 0);
157
158 std::cout << "Grid size: " << 256 << "x" << 256
159 << " = " << GRID_SIZE << " cells\n";
160 std::cout << "Memory per grid: " << sizeof(Cell) * GRID_SIZE / 1024
161 << " KB\n";
162
163 // Initialize grid
164 for (size_t i = 0; i < 100; ++i) {
165 grid_current[i].density = 1.0f;
166 grid_current[i].type = 1;
167 }
168
169 // Simulate one step (simplified)
170 for (size_t y = 1; y < 255; ++y) {
171 for (size_t x = 1; x < 255; ++x) {
172 size_t idx = y * 256 + x;
173
174 // Simple diffusion
175 float avg_density = (
176 grid_current[idx - 256].density + // North
177 grid_current[idx + 256].density + // South
178 grid_current[idx - 1].density + // West
179 grid_current[idx + 1].density // East
180 ) * 0.25f;
181
182 grid_next[idx].density = avg_density;
183 }
184 }
185
186 step_counter++;
187 std::cout << "Simulation at step: " << step_counter.load() << "\n";
188}
189
191 std::cout << "\n=== Common Simulation Patterns ===\n\n";
192
193 std::cout << "1. Object Pool (shm_object_pool):\n";
194 std::cout << " - Dynamic entity management (particles, enemies, projectiles)\n";
195 std::cout << " - Avoids fragmentation, O(1) allocation\n";
196 std::cout << " - Perfect for systems with many temporary objects\n\n";
197
198 std::cout << "2. Ring Buffer (shm_ring_buffer):\n";
199 std::cout << " - Sensor data streams\n";
200 std::cout << " - Event/message logging\n";
201 std::cout << " - Time-series data with bulk operations\n\n";
202
203 std::cout << "3. Fixed Arrays (shm_array):\n";
204 std::cout << " - Spatial grids (collision, physics, fluid)\n";
205 std::cout << " - Lookup tables\n";
206 std::cout << " - Double-buffered state\n\n";
207
208 std::cout << "4. Atomics (shm_atomic):\n";
209 std::cout << " - Global counters and statistics\n";
210 std::cout << " - Synchronization flags\n";
211 std::cout << " - Lock-free coordination\n\n";
212
213 std::cout << "5. Queues (shm_queue):\n";
214 std::cout << " - Task distribution\n";
215 std::cout << " - Event handling\n";
216 std::cout << " - Producer-consumer patterns\n";
217}
218
219int main() {
220 try {
225
226 std::cout << "\n=== All simulation patterns demonstrated successfully! ===\n";
227 } catch (const std::exception& e) {
228 std::cerr << "Error: " << e.what() << std::endl;
229 return 1;
230 }
231
232 return 0;
233}
Fixed-size array in shared memory with zero-overhead access.
Definition shm_array.h:63
Shared memory atomic value with auto-discovery.
Definition shm_atomic.h:19
T load(std::memory_order order=std::memory_order_seq_cst) const noexcept
Definition shm_atomic.h:88
High-performance object pool for shared memory.
void release(handle_type handle) noexcept
Release an object back to the pool.
size_t capacity() const noexcept
Get pool statistics.
std::optional< handle_type > acquire_construct(Args &&... args)
Acquire and construct an object.
size_t num_allocated() const noexcept
Lock-free ring buffer for high-throughput streaming data.
size_t pop_bulk(std::span< T > values) noexcept
Pop multiple elements efficiently.
bool push(const T &value) noexcept
Push a single element.
size_t get_last_n(size_t n, std::span< T > values) const noexcept
Get the last N elements (most recent) Useful for getting trailing sensor data.
size_t size() const noexcept
uint64_t total_written() const noexcept
Get total elements written (useful for monitoring data rate)
Core POSIX shared memory management with automatic reference counting.
Fixed-size shared memory array with STL compatibility.
void particle_simulation_example()
void usage_patterns()
void grid_simulation_example()
void sensor_streaming_example()
int main()