aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-03-21 16:29:12 +0100
committerJulian T <julian@jtle.dk>2020-03-23 16:56:59 +0100
commitb82c067167ac2b4d295d459cea6e26434f889c8d (patch)
treeca8bd98b938082feb620504db87324276967e3de
parent83b552b622da561de047f798e5d50d59f724b1eb (diff)
Multithreaded rendering working
-rw-r--r--Makefile2
-rw-r--r--main.c108
-rw-r--r--ray.h1
-rw-r--r--test.pngbin693556 -> 694523 bytes
4 files changed, 92 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index aec3efe..49416a0 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ CC=gcc
CFLAGS=-ggdb
# We need math
-LDFLAGS=-lm
+LDFLAGS=-lm -lpthread
# Output and build options
BINARY=raytrace
diff --git a/main.c b/main.c
index c27096c..630d4dc 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
+#include <pthread.h>
#include "vector.h"
#include "ray.h"
@@ -10,7 +11,23 @@
#define TESTW 1000
#define TESTH 1000
+#define PERCENTSTEP (TESTH / 100)
+
+#define WORKERS 4
+
+void *worker_func(void *arg);
+
+typedef struct {
+ unsigned id;
+ color_t *image;
+} office_t;
+
+// Height percentage, workers take turn at printing to it. This maaaay be a bad idea
+unsigned percent = 0;
+pthread_mutex_t percentlock;
+
char container[ CONTAINER_SIZE(5, 4, 1) ];
+container_t *cont = (container_t *) container;
// Implement random
COORD_T ray_rand(void *seed)
@@ -20,8 +37,6 @@ COORD_T ray_rand(void *seed)
int main()
{
-
- container_t *cont = (container_t *) container;
container_init(cont, 5, 4, 1);
// Init space_t
@@ -62,14 +77,12 @@ int main()
m2->reflective = 1;
material_t *mpl = add_material(cont);
- //vector_set(&mpl.color, 0, 0.396, 0.7019);
vector_set(&mpl->color, 1, 1, 1);
mpl->defuse = 1;
mpl->specular = 0.0;
mpl->shine = 50;
mpl->reflective = 0.0;
-
viewpoint_init(&s->view);
object_t *o = add_object(cont, TYPE_SPHERE);
@@ -104,25 +117,86 @@ int main()
pgm_write_header(stdout, TESTW, TESTH);
- // Height percentage
- unsigned percentstep = TESTH / 100;
- unsigned percent = 0;
- int seed;
+ // Create image array. Not as memory efficient but much simpler when multiprocessing
+ color_t *image = malloc( sizeof(color_t) * TESTW * TESTH);
+ if (!image) {
+ fprintf(stderr, "Could not allocate image array");
+ exit(1);
+ }
- for (int y = TESTH; y; y--) {
- for (int x = TESTW; x; x--) {
- // Random seed
- seed = x * y;
- color_t c;
- ray_trace(&cont->space, x, y, 2, &c, &seed);
+ if (pthread_mutex_init(&percentlock, NULL)) {
+ fprintf(stderr, "Could not percent lock\n");
+ exit(1);
+ }
+
+ // Hire the workers
+ pthread_t workers[WORKERS];
+ for (int i = 0; i < WORKERS; i++) {
+ office_t *office = malloc(sizeof(office_t));
+ office->id = i;
+ office->image = image;
+
+ // Start them and show them their office(chunk in the array in this case :-D)
+ int rc = pthread_create(&workers[i], NULL, worker_func, office);
+ if (rc) {
+ fprintf(stderr, "Could not create worker %d\nsorry\n", i);
+ exit(1);
+ }
+ }
+
+ // Wait for the threads to finish and print as we go
+ for (int i = 0; i < WORKERS; i++) {
+ pthread_join(workers[i], NULL);
+
+ }
+
+ // Print the stuff the worker was responsable for.
+ for (int y = 0; y < TESTH; y++) {
+ for(int x = 0; x < TESTW; x++) {
+ pgm_write_pixel(stdout, &image[ y * TESTW + x]);
+ }
+ }
- pgm_write_pixel(stdout, &c);
+ free(image);
+
+}
+void *worker_func(void *arg) {
+ // Organize our office
+ office_t *office = (office_t *) arg;
+
+ // Timing
+ double rowtime = 0;
+ unsigned count = 0;
+ int seed;
+
+ // Start working
+ for (int y = office->id; y < TESTH; y += WORKERS) {
+ // Start time
+ clock_t t = clock();
+ count++;
+
+ for (int x = 0; x < TESTW; x++) {
+ color_t *c = &office->image[ y * TESTW + x ];
+ //color_t c;
+ seed = x * y;
+ ray_trace(&cont->space, TESTW - x, TESTH - y, 2, c, &seed);
}
- if (y % percentstep == 0) {
+ // Time stop
+ t = clock() - t;
+ rowtime += ((double)t)/CLOCKS_PER_SEC; // in seconds
+
+ if (y % PERCENTSTEP == 0) {
+ // Unlock the thingy
+ pthread_mutex_lock(&percentlock);
fprintf(stderr, "%d%\n", percent++);
+ pthread_mutex_unlock(&percentlock);
}
}
-
+
+ fprintf(stderr, "Mean row time %lf over %d rounds\n", rowtime / count, count);
+
+ //free(office);
+ pthread_exit(NULL);
}
diff --git a/ray.h b/ray.h
index 03756e3..085b661 100644
--- a/ray.h
+++ b/ray.h
@@ -22,5 +22,4 @@ COORD_T ray_intersect_plane(plane_t *p, ray_t *ray, bool skip_dist);
object_t *ray_cast(space_t *s, ray_t *r, COORD_T *dist_ret, bool chk, COORD_T chk_dist);
void ray_trace(space_t *s, unsigned int x, unsigned int y, unsigned samples, color_t *c, void *seed);
-
#endif
diff --git a/test.png b/test.png
index 78b7f9f..d378e88 100644
--- a/test.png
+++ b/test.png
Binary files differ