]> git.mcshandy.xyz Git - barrow_crawler/commitdiff
threading rework and it seems to be working, with actual speedups
authorRandy McShandy <randy@mcshandy.xyz>
Wed, 13 Dec 2023 04:38:39 +0000 (22:38 -0600)
committerRandy McShandy <randy@mcshandy.xyz>
Wed, 13 Dec 2023 04:38:39 +0000 (22:38 -0600)
main.c

diff --git a/main.c b/main.c
index 057f71dd73b5e3ae7838561f70589967e5d7d12e..574da26a88b773cbf03ad38322b323476afe781f 100755 (executable)
--- 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");