summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2023-08-26 00:51:17 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2023-08-26 00:51:17 +0100
commit026aa887f99d87932fd5316152a15c1a79f5a6e2 (patch)
tree752e4b9c2f12c1fcb983ab0e02f1d2b6abc286e2 /main.c
parent1bc283b195fb6f7152a5b98385f019056e95d637 (diff)
downloadabelian-sandpile-026aa887f99d87932fd5316152a15c1a79f5a6e2.tar.gz
abelian-sandpile-026aa887f99d87932fd5316152a15c1a79f5a6e2.tar.bz2
abelian-sandpile-026aa887f99d87932fd5316152a15c1a79f5a6e2.zip
+further multithreading
I split the grid into 4 quadrants which are managed by their own thread. Improves speed and uses more resources correctly.
Diffstat (limited to 'main.c')
-rw-r--r--main.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/main.c b/main.c
index 18b0f5e..c93660e 100644
--- a/main.c
+++ b/main.c
@@ -17,12 +17,22 @@
#include "./lib.h"
-void step(state_t *state)
+struct StepArg
{
- for (size_t i = 0; i < state->dwidth; ++i)
- for (size_t j = 0; j < state->dwidth; ++j)
+ state_t *state;
+ size_t x_min, x_max, y_min, y_max;
+};
+
+pthread_mutex_t mutex;
+
+void step(struct StepArg arg)
+{
+ state_t *state = arg.state;
+ for (size_t i = arg.x_min; i < arg.x_max; ++i)
+ for (size_t j = arg.y_min; j < arg.y_max; ++j)
if (state->data[(i * state->dwidth) + j] >= 4)
{
+ pthread_mutex_lock(&mutex);
uint64_t *references[] = {
(j == 0) ? NULL : &state->data[((i)*state->dwidth) + j - 1],
(i == state->dwidth - 1)
@@ -36,29 +46,43 @@ void step(state_t *state)
if (references[k])
*references[k] += state->data[(i * state->dwidth) + j] / 4;
state->data[(i * state->dwidth) + j] %= 4;
+ pthread_mutex_unlock(&mutex);
}
}
void *compute_thread(void *input)
{
- state_t *state = input;
- while (state->thread_alive)
- step(state);
+ struct StepArg *arg = input;
+ while (arg->state->thread_alive)
+ step(*arg);
return NULL;
}
int main(void)
{
- state_t state = {NULL, 512, 512, 0, true};
+ state_t state = {NULL, 512, 512, 0, true, pow(2, 20)};
state.data = calloc(state.dwidth * state.dwidth, sizeof(*state.data));
state.multiplier = state.window_len / state.dwidth;
+ state.data[(state.dwidth * state.dwidth / 2) + (state.dwidth / 2)] =
+ state.payload;
const float zoom = 0.125f;
Camera2D camera = {0};
camera.zoom = 1.0f;
- pthread_t step_thread;
- pthread_create(&step_thread, NULL, &compute_thread, &state);
+ pthread_mutex_init(&mutex, NULL);
+ struct StepArg a = {&state, 0, state.dwidth / 2, 0, state.dwidth / 2};
+ struct StepArg b = {&state, 0, state.dwidth / 2, state.dwidth / 2,
+ state.dwidth};
+ struct StepArg c = {&state, state.dwidth / 2, state.dwidth, 0,
+ state.dwidth / 2};
+ struct StepArg d = {&state, state.dwidth / 2, state.dwidth, state.dwidth / 2,
+ state.dwidth};
+ pthread_t thread_a, thread_b, thread_c, thread_d;
+ pthread_create(&thread_a, NULL, &compute_thread, &a);
+ pthread_create(&thread_b, NULL, &compute_thread, &b);
+ pthread_create(&thread_c, NULL, &compute_thread, &c);
+ pthread_create(&thread_d, NULL, &compute_thread, &d);
InitWindow(state.window_len, state.window_len, "Abelian sand pile");
SetTargetFPS(60);
@@ -119,10 +143,14 @@ int main(void)
if (state.thread_alive)
{
state.thread_alive = false;
- pthread_join(step_thread, NULL);
+ pthread_join(thread_a, NULL);
+ pthread_join(thread_b, NULL);
+ pthread_join(thread_c, NULL);
+ pthread_join(thread_d, NULL);
}
CloseWindow();
+
unsigned char *image_data =
calloc(3 * state.dwidth * state.dwidth, sizeof(*image_data));