14double benchmark(
const std::string& name, Func f,
size_t iterations = 1000000) {
15 auto start = high_resolution_clock::now();
17 for (
size_t i = 0; i < iterations; ++i) {
21 auto end = high_resolution_clock::now();
22 auto ns = duration_cast<nanoseconds>(end - start).count();
23 double ns_per_op =
static_cast<double>(ns) / iterations;
25 std::cout << name <<
": " << ns_per_op <<
" ns/operation\n";
30 constexpr size_t ARRAY_SIZE = 10000;
34 std::random_device rd;
35 std::mt19937 gen(rd());
36 std::uniform_int_distribution<> dist(0, ARRAY_SIZE - 1);
38 for (
auto& idx : indices) {
42 std::cout <<
"=== Read Performance Benchmark ===\n";
43 std::cout <<
"Array size: " << ARRAY_SIZE <<
" integers\n";
44 std::cout <<
"Iterations: " <<
ITERATIONS <<
"\n\n";
47 auto* heap_array =
new int[ARRAY_SIZE];
48 std::iota(heap_array, heap_array + ARRAY_SIZE, 0);
51 constexpr size_t STACK_SIZE = 1000;
52 int stack_array[STACK_SIZE];
53 std::iota(stack_array, stack_array + STACK_SIZE, 0);
56 posix_shm shm(
"benchmark_shm", 10 * 1024 * 1024);
58 std::iota(shared_array.
begin(), shared_array.
end(), 0);
61 int* shared_raw_ptr = shared_array.
data();
63 volatile int sink = 0;
65 std::cout <<
"Sequential Read Performance:\n";
66 std::cout <<
"-----------------------------\n";
71 benchmark(
"Heap array (sequential)", [&]() {
72 sink = heap_array[seq_idx];
73 seq_idx = (seq_idx + 1) % ARRAY_SIZE;
77 benchmark(
"Stack array (sequential)", [&]() {
78 sink = stack_array[seq_idx];
79 seq_idx = (seq_idx + 1) % STACK_SIZE;
83 benchmark(
"Shared array operator[] (sequential)", [&]() {
84 sink = shared_array[seq_idx];
85 seq_idx = (seq_idx + 1) % ARRAY_SIZE;
89 benchmark(
"Shared array raw pointer (sequential)", [&]() {
90 sink = shared_raw_ptr[seq_idx];
91 seq_idx = (seq_idx + 1) % ARRAY_SIZE;
94 std::cout <<
"\nRandom Access Performance:\n";
95 std::cout <<
"-----------------------------\n";
101 sink = heap_array[indices[rand_idx]];
106 benchmark(
"Shared array operator[] (random)", [&]() {
107 sink = shared_array[indices[rand_idx]];
112 benchmark(
"Shared array raw pointer (random)", [&]() {
113 sink = shared_raw_ptr[indices[rand_idx]];
117 std::cout <<
"\nBulk Operations Performance:\n";
118 std::cout <<
"-----------------------------\n";
122 sink = std::accumulate(heap_array, heap_array + 1000, 0);
125 benchmark(
"Shared array sum (iterators)", [&]() {
126 sink = std::accumulate(shared_array.
begin(), shared_array.
begin() + 1000, 0);
129 benchmark(
"Shared array sum (raw pointer)", [&]() {
130 sink = std::accumulate(shared_raw_ptr, shared_raw_ptr + 1000, 0);
133 std::cout <<
"\n=== Key Findings ===\n";
134 std::cout <<
"1. Sequential reads: Shared memory matches heap/stack performance\n";
135 std::cout <<
"2. Random reads: Same cache miss penalty for all\n";
136 std::cout <<
"3. Raw pointer access: Identical to normal arrays\n";
137 std::cout <<
"4. operator[] overhead: Minimal (usually inlined)\n";
138 std::cout <<
"5. After setup, it's just memory!\n";