From a7196f9000c5beb2ee8c0290eb54771bfa4238dc Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Thu, 29 Oct 2020 21:57:57 -0500 Subject: [PATCH] added first parallel version --- Makefile | 2 +- src/sim.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 75ee0ae..edeb4e3 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ LIB_FILES=\ CC=g++ INCLUDES=-I./include -LIBS=-lGL -lglfw -lm +LIBS=-lGL -lglfw -lm -lpthread TARGET=./sim ifeq ($(RELEASE), 1) diff --git a/src/sim.cpp b/src/sim.cpp index 5103e72..00b4f1a 100644 --- a/src/sim.cpp +++ b/src/sim.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -26,7 +27,10 @@ #define WINDOW_TITLE "N-Body Simulation" // :ArbitraryConstant -#define PARTICLE_COUNT 2500 +#define PARTICLE_COUNT 3000 + +// :ArbitraryConstant +#define NUM_THREADS 2 // TODO(Brendan): Maybe this can be removed because it isn't really necessary? internal void @@ -127,6 +131,51 @@ struct SimState Camera camera; }; +internal void +update_bodies_partial(SimState *state, i32 index) +{ + i32 low = index * (PARTICLE_COUNT / NUM_THREADS); + i32 high = (index + 1) * (PARTICLE_COUNT / NUM_THREADS); + + persist const f64 step = 0.01; + + foreach (i, low, high) + { + body_accumulate_move(&state->bodies[i], &state->qt_bodies, step); + } + + foreach (i, low, high) + { + body_apply_move(&state->bodies[i], step); + } +} + +internal pthread_barrier_t thread_sync_barrier; +internal pthread_t threads[NUM_THREADS - 1]; + +struct ThreadData +{ + i32 id; + SimState* state; +}; + +internal void* +thread_start(void* data) +{ + i32 thread_id = ((ThreadData *) data)->id; + SimState* state = ((ThreadData *) data)->state; + + while (true) + { + pthread_barrier_wait(&thread_sync_barrier); + update_bodies_partial(state, thread_id + 1); + pthread_barrier_wait(&thread_sync_barrier); + pthread_barrier_wait(&thread_sync_barrier); + } + + return NULL; +} + internal void sim_state_init(SimState* state) { @@ -146,8 +195,17 @@ sim_state_init(SimState* state) state->qt_body_allocator.init(PARTICLE_COUNT); - state->camera.offset = V2f { 0, 0 }; state->camera.scale = 1.0f; + + pthread_barrier_init(&thread_sync_barrier, NULL, NUM_THREADS); + + foreach (i, 0, NUM_THREADS - 1) + { + auto td = alloc(1); // LEAK + td->id = i; + td->state = state; + pthread_create(&threads[i], NULL, thread_start, (void *) td); + } } // NOTE(Brendan): dt is expected to be in units of "per second". @@ -164,14 +222,13 @@ update(SimState* state, f64 dt) if (glfwGetKey(window, GLFW_KEY_Q)) state->camera.scale *= 1.01f; if (glfwGetKey(window, GLFW_KEY_A)) state->camera.scale /= 1.01f; - persist const f64 step = 0.01; - state->qt_bodies.init(AABB { -2000, -2000, 4000, 4000 }); state->qt_body_allocator.reset(); For (state->bodies) state->qt_bodies.insert(&it, &state->qt_body_allocator); + pthread_barrier_wait(&thread_sync_barrier); - For (state->bodies) body_accumulate_move(&it, &state->qt_bodies, step); - For (state->bodies) body_apply_move(&it, step); + update_bodies_partial(state, 0); + pthread_barrier_wait(&thread_sync_barrier); } // NOTE CLEANUP(Brendan): Bunch of graphics state that should go elsewhere. @@ -219,6 +276,7 @@ draw(SimState* state) // NOTE(Brendan): Present the changes to the screen. glfwSwapBuffers(window); + pthread_barrier_wait(&thread_sync_barrier); } internal void -- 2.25.1