diff options
author | David Phillips <dbphillipsnz@gmail.com> | 2015-06-09 15:08:32 +1200 |
---|---|---|
committer | David Phillips <dbphillipsnz@gmail.com> | 2015-06-09 15:08:32 +1200 |
commit | 10010ff5d5e601e47eac14fff6bb4fa644be57f2 (patch) | |
tree | 4f75b6f74cab34efb305f257111ad426b4df1660 | |
parent | 611ed259391c4c311c214b72a92ce111101a8281 (diff) | |
download | fractal-gen-10010ff5d5e601e47eac14fff6bb4fa644be57f2.tar.xz |
Fixed a few known bugs when threads wasn't a multiple of the size
-rw-r--r-- | fractal-gen.c | 41 | ||||
-rw-r--r-- | mbrot.c | 2 |
2 files changed, 33 insertions, 10 deletions
diff --git a/fractal-gen.c b/fractal-gen.c index 1a77577..79f2de7 100644 --- a/fractal-gen.c +++ b/fractal-gen.c @@ -5,6 +5,7 @@ int main(int argc, char **argv) unsigned int size, iterat, cores, i, x, y; double power; char* bname; + data_section* sections; void *(*generator)(void *); // Select correct generator for the fractal type @@ -19,7 +20,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - if (argc != 4 || argc != 5) + if (argc != 4 && argc != 5) { fprintf(stderr, "%s size iterat power [threads]\n", argv[0]); return EXIT_FAILURE; @@ -29,17 +30,24 @@ int main(int argc, char **argv) iterat = atoi(argv[2]); power = atof(argv[3]); - // Fetch number of cores available on machine - // FIXME make the num threads selectable - cores = sysconf(_SC_NPROCESSORS_ONLN); + cores = argc == 5? atoi(argv[4]) : sysconf(_SC_NPROCESSORS_ONLN); // Screw maintainability ;) + + // Interlacing is column-based, can't have more workers than columns + if (cores > size) + { + fprintf(stderr, "WARN: Capping number of threads to image width\n"); + cores = size; + } assert(size > 0); assert(iterat > 0); assert(cores > 0); // Allocated memory for sections, bailing upon failure - data_section* sections = malloc(sizeof(data_section)*cores); + sections = malloc(sizeof(data_section)*cores); + + if (sections == NULL) { perror("malloc"); @@ -56,18 +64,31 @@ int main(int argc, char **argv) sections[i].size = size; sections[i].power = power; sections[i].iterat = iterat; - sections[i].data = malloc((size*size)/cores); + +int s; + + // A bit complex, icky, will document later + if (i < (size%cores)) + s = (size*((int)(size/cores)+1)); + else + s = (size*(int)(size/cores)); + + sections[i].data = malloc(s); + + if (sections[i].data == NULL) { + fprintf(stderr, "\n"); + perror("malloc"); // Free already allocated chunks of memory + i--; while(i-- + 1) free(sections[i].data); free(sections); - perror("malloc"); return EXIT_FAILURE; } - fprintf(stderr, " -> Thread #%d\n", i); + fprintf(stderr, " -> Thread #%d (%d)\r", i+1, s); pthread_create(§ions[i].thread, NULL, generator, &(sections[i])); } @@ -75,6 +96,7 @@ int main(int argc, char **argv) for (i = 0; i < cores; i++) pthread_join(sections[i].thread, NULL); + // Output PGM Header printf("P5\n%d\n%d\n255\n",size,size); @@ -84,11 +106,12 @@ int main(int argc, char **argv) for (x = 0; x < size; x++) putchar(sections[y%cores].data[(y/cores)*size + x]); + fprintf(stderr, "\nDone\n"); + // Free the memory we allocated for point data for (i = 0; i < cores; i++) free(sections[i].data); free(sections); - fprintf(stderr,"\n"); return 0; } @@ -8,6 +8,7 @@ void *generate_mbrot_section(void *section) double a,b; double complex z,c; + 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++) @@ -21,7 +22,6 @@ void *generate_mbrot_section(void *section) z = cpow(z, d->power)+c; } - d->data[idx++] = (255*i)/d->iterat; } } |