From 4710dbeef96a84c81c1b11e0b5164f9918b64cd4 Mon Sep 17 00:00:00 2001 From: Randy McShandy Date: Tue, 12 Dec 2023 22:38:39 -0600 Subject: [PATCH] threading rework and it seems to be working, with actual speedups --- main.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index 057f71d..574da26 100755 --- a/main.c +++ b/main.c @@ -57,6 +57,7 @@ typedef struct int* waiting_workers; int worker_count; + int iterations; int max_iterations; int worker_id; } worker_arg; @@ -180,6 +181,75 @@ float rd_b_prime(FVec2** source_grid, RD_Opts opts, int x, int y, Mat3 kernel, f } void* iterator(void* _arg) +{ + worker_arg* warg = (worker_arg*)_arg; + RD_Opts opts = warg->opts; + int start_x = warg->start_x; + int start_y = warg->start_y; + int w = warg->width;//(warg->width + start_x >= GRID_X) ? GRID_X-1 - start_x: warg->width; + int h = warg->height;//(warg->height + start_y >= GRID_Y) ? GRID_Y-1 - start_y : warg->height; + + for (warg->iterations = 0; warg->iterations < warg->max_iterations; warg->iterations++) + { + printf("worker %d: work unit %d/%d\n", warg->worker_id, warg->iterations, warg->max_iterations); + for (int x = start_x; x < w + start_x; x++) + { + for (int y = start_y; y < h + start_y; y++) + { + FVec2 each = grid[x][y]; + grid_prime[x][y].a = rd_a_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b); + grid_prime[x][y].b = rd_b_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b); + } + } + +#if 1 + // Last one done should wake up the boss thread + int last_worker = 0; + pthread_mutex_lock(warg->mutex); + if (++*warg->waiting_workers == warg->worker_count) + { + last_worker = 1; + } + pthread_mutex_unlock(warg->mutex); + + if (last_worker == 0) + { + pthread_cond_wait(warg->worker_cond, &warg->worker_mutex); + } + else + { + grid_temp = grid; + grid = grid_prime; + grid_prime = grid_temp; + + // segfault somewhere in here lmao + if (1 && (warg->iterations % 100 == 0)) + { + char buffer[GRID_X][GRID_Y]; + for (int x = 0; x < GRID_X; x++) + { + for (int y = 0; y < GRID_Y; y++) + { + buffer[x][y] = (uint8_t)(255.0f * grid[x][y].a); + } + } + char name[64] = {0}; + sprintf(name, "img/%s/%d.png", opts.name, warg->iterations); + stbi_write_png(name, GRID_X, GRID_Y, 1, buffer, GRID_X * sizeof(uint8_t)); + } + printf("worker-boss %d: completing report\n", warg->worker_id); + + *warg->waiting_workers = 0; + pthread_cond_broadcast(warg->worker_cond); + } +#endif + } + + printf("worker %d: exiting\n", warg->worker_id); + return _arg; +} + +void* iterator_old(void* _arg) { worker_arg* warg = (worker_arg*)_arg; RD_Opts opts = warg->opts; @@ -201,9 +271,15 @@ void* iterator(void* _arg) } } + // Last one done should wake up the boss thread + pthread_mutex_lock(warg->mutex); ++*warg->waiting_workers; - printf("worker %d: waking up boss\n", warg->worker_id); - pthread_cond_signal(warg->boss_cond); + if (*warg->waiting_workers == warg->worker_count) + { + printf("worker %d: waking up boss\n", warg->worker_id); + pthread_cond_signal(warg->boss_cond); + } + pthread_mutex_unlock(warg->mutex); pthread_cond_wait(warg->worker_cond, &warg->worker_mutex); @@ -272,7 +348,7 @@ int main(int argc, char** argv) { wargs[t] = warg; wargs[t].worker_id = t; - wargs[t].width = (GRID_X/warg.worker_count); + wargs[t].width = (GRID_X/warg.worker_count) + ((t == warg.worker_count-1) ? 0 : 4); wargs[t].start_x = (wargs[t].width * t); pthread_mutex_init(&wargs[t].worker_mutex, NULL); printf("worker %d x_span %d, %d\n", t, wargs[t].start_x, wargs[t].width); @@ -281,13 +357,16 @@ int main(int argc, char** argv) int max_iterations = (GRID_X / 128.0f) * opts.max_iterations; max_iterations = warg.max_iterations; + /* for (int iterations = 0; iterations < max_iterations; iterations++) { printf("boss: waiting on workers\n"); + pthread_mutex_lock(warg.mutex); while (*warg.waiting_workers < warg.worker_count) { pthread_cond_wait(warg.boss_cond, warg.mutex); } + pthread_mutex_unlock(warg.mutex); grid_temp = grid; grid = grid_prime; @@ -311,8 +390,16 @@ int main(int argc, char** argv) } } - *warg.waiting_workers = 0; - pthread_cond_broadcast(warg.worker_cond); + } + */ + + int should_quit = 0; + while(!should_quit) + { + pthread_mutex_lock(warg.mutex); + if (wargs[0].iterations == wargs[0].max_iterations-1) + should_quit = 1; + pthread_mutex_unlock(warg.mutex); } printf("boss: exiting loop\n"); -- 2.49.0