diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | bship.c | 38 | ||||
-rw-r--r-- | fractal-gen.c | 78 | ||||
-rw-r--r-- | fractal-gen.h | 28 | ||||
-rw-r--r-- | mbrot.c | 38 |
5 files changed, 188 insertions, 2 deletions
@@ -4,8 +4,11 @@ symlinks: fractal-gen ln -sf $< mbrot-gen ln -sf $< bship-gen -fractal-gen: fractal-gen.c - $(CC) -o $@ $< -lm -lpthread -Wall -Wextra -Werror +fractal-gen: fractal-gen.o mbrot.o bship.o + $(CC) -o $@ $? -lm -lpthread + +%.o: %.c + $(CC) -c -o $@ $< -Wall -Wextra -Werror .PHONY: all clean @@ -13,4 +16,5 @@ clean: rm fractal-gen \ mbrot-gen \ bship-gen \ + *.o \ -f @@ -0,0 +1,38 @@ +#include "fractal-gen.h" + +void *generate_bship_section(void *section) +{ + data_section *d = (data_section*)section; + unsigned int x,y,i; + int idx = 0; + double a,b; + double complex z,c; + + + d->data = malloc((d->size*d->size)/d->cores); + if (d->data == NULL) + { + perror("malloc"); + return NULL; + } + + + for (y = d->core, b = (d->core*(3.5f/d->size)-1.75f); y < d->size; b+=((d->cores*3.5f)/d->size), y+=d->cores) + { + for (x = 0, a = -2.5f; x < d->size; a+=(3.5f/d->size), x++) + { + z = 0; + c = a+I*b; + for (i = 0; i < d->iterat; i++) + { + if (cabsf(z) >= 2) + break; + + z = cpow( cabsf(crealf(z)) + I*cabsf(cimagf(z)) , d->power) + c; + } + + d->data[idx++] = (255*i)/d->iterat; + } + } + return NULL; +} diff --git a/fractal-gen.c b/fractal-gen.c new file mode 100644 index 0000000..6f3cb5f --- /dev/null +++ b/fractal-gen.c @@ -0,0 +1,78 @@ +#include "fractal-gen.h" + +int main(int argc, char **argv) +{ + unsigned int size, iterat, cores, i, x, y, s; + double power; + void *(*generator)(void *); + + // Select correct generator for the fractal type + // TO DO: use basename + if (strcmp(argv[0], "./mbrot-gen") == 0) + generator = &generate_mbrot_section; + else if (strcmp(argv[0], "./bship-gen") == 0) + generator = &generate_bship_section; + else + fprintf(stderr, "Don't call this directly, call a symlink to me\n"); + + if (argc != 4) + { + fprintf(stderr, "%s size iterat power\n", argv[0]); + return EXIT_FAILURE; + } + + size = atoi(argv[1]); + iterat = atoi(argv[2]); + power = atof(argv[3]); + + + // Fetch number of cores available on machine + cores = sysconf(_SC_NPROCESSORS_ONLN); + + assert(size > 0); + assert(iterat > 0); + assert(cores > 0); + + + + // Allocated memory for sections, bailing upon failure + data_section* sections = malloc(sizeof(data_section)*cores); + if (sections == NULL) + { + perror("malloc"); + return EXIT_FAILURE; + } + + fprintf(stderr, "Spawning %d threads:\n", cores); + // Spawn all the threads! Something something interlacing + for (i = 0; i < cores; i++) + { + // Has to be a better way + sections[i].core = i; + sections[i].cores = cores; + sections[i].size = size; + sections[i].power = power; + sections[i].iterat = iterat; + + fprintf(stderr, " -> Thread #%d\n", i); + pthread_create(§ions[i].thread, NULL, generator, &(sections[i])); + } + + // Wait for each thread to complete + for (i = 0; i < cores; i++) + pthread_join(sections[i].thread, NULL); + + // Vomit the data segments back onto the screen, deinterlacing + // TO DO: look at fwrite performance benefits over putchar + for (y = 0; y < size; y++) + for (x = 0; x < size; x++) + putchar(sections[y%cores].data[(y/cores)*size + x]); + + // Free the memory we allocated for point data + for (s = 0; s < cores; s++) + free(sections[s].data); + + free(sections); + fprintf(stderr,"\n"); + return 0; +} diff --git a/fractal-gen.h b/fractal-gen.h new file mode 100644 index 0000000..99d41ff --- /dev/null +++ b/fractal-gen.h @@ -0,0 +1,28 @@ +#ifndef FRACTAL_GEN_H +#define FRACTAL_GEN_H + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <complex.h> +#include <math.h> +#include <unistd.h> +#include <pthread.h> +#include <assert.h> + +typedef struct +{ + unsigned int core; + unsigned int cores; + unsigned int size; + double power; + unsigned int iterat; + char* data; + pthread_t thread; +} data_section; + +void *generate_mbrot_section(void *d); +void *generate_bship_section(void *d); + + +#endif @@ -0,0 +1,38 @@ +#include "fractal-gen.h" + +void *generate_mbrot_section(void *section) +{ + data_section *d = (data_section*)section; + unsigned int x,y,i; + int idx = 0; + double a,b; + double complex z,c; + + + d->data = malloc((d->size*d->size)/d->cores); + if (d->data == NULL) + { + perror("malloc"); + return NULL; + } + + + for (y = d->core, b = (d->core*(3.5f/d->size)-1.75f); y < d->size; b+=((d->cores*3.5f)/d->size), y+=d->cores) + { + for (x = 0, a = -2.5f; x < d->size; a+=(3.5f/d->size), x++) + { + z = 0; + c = a+I*b; + for (i = 0; i < d->iterat; i++) + { + if (cabsf(z) >= 2) + break; + + z = cpow(z, d->power)+c; + } + + d->data[idx++] = (255*i)/d->iterat; + } + } + return NULL; +} |