Cleanup: Improved main file readablilty and redundant code
This commit is contained in:
+154
-184
@@ -21,173 +21,10 @@ const uint16_t NUMBER_OF_VERSIONS = 4;
|
|||||||
|
|
||||||
|
|
||||||
void save_bmp(const char *filename, unsigned char *img, size_t width, ssize_t height,_Bool color);
|
void save_bmp(const char *filename, unsigned char *img, size_t width, ssize_t height,_Bool color);
|
||||||
|
void benchmarking(size_t benchmarking_amount, int version_to_use, float complex complexA, size_t width, ssize_t height, float resolution, unsigned n, _Bool colored);
|
||||||
|
unsigned tests(void);
|
||||||
|
void checkInputs(_Bool n,_Bool r,_Bool o,_Bool d,_Bool s);
|
||||||
|
|
||||||
void benchmarking(size_t benchmarking_amount, int version_to_use, float complex complexA, size_t width, ssize_t height, float resolution, unsigned n, _Bool colored) {
|
|
||||||
struct timespec start;
|
|
||||||
struct timespec end;
|
|
||||||
void (*tricorn_implementation)(float complex, size_t, ssize_t, float, unsigned, _Bool, unsigned char*);
|
|
||||||
|
|
||||||
unsigned int bytePerColor = colored ? 3 : 1;
|
|
||||||
unsigned char *tempArr = malloc(width*height*bytePerColor);
|
|
||||||
if(tempArr == NULL) {
|
|
||||||
fprintf(stderr,"Could not allocate memory for buffer");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (version_to_use)
|
|
||||||
{
|
|
||||||
case 0: // Uses highly optimized SIMD and threaded version / main implementation
|
|
||||||
printf("Benchmarking V0 - highly optimized SIMD\n");
|
|
||||||
tricorn_implementation = tricorn;
|
|
||||||
break;
|
|
||||||
case 1: // Uses unoptimised scalar comparison implementation
|
|
||||||
printf("Benchmarking V1 - scalar comparison implementation\n");
|
|
||||||
tricorn_implementation = tricorn_V1;
|
|
||||||
break;
|
|
||||||
case 2: // Uses optimized SISD implementation
|
|
||||||
printf("Benchmarking V2 - unoptimized SIMD implementation\n");
|
|
||||||
tricorn_implementation = tricorn_V2;
|
|
||||||
break;
|
|
||||||
case 3: // Uses unoptimized SIMD implementation
|
|
||||||
printf("Benchmarking V3 - highly optimized SIMD + Threading implementation\n");
|
|
||||||
tricorn_implementation = tricorn_V3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr,"Invalid version to use: V%d. Available versions are : V0,V1,V2,V3,V4,V5\n",version_to_use);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
|
||||||
for (size_t i = 0; i < benchmarking_amount; i++)
|
|
||||||
{
|
|
||||||
tricorn_implementation(complexA,width,height,resolution,n,colored,tempArr);
|
|
||||||
}
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
|
||||||
|
|
||||||
double time = end.tv_sec- start.tv_sec + 1e-9 * (end.tv_nsec- start.tv_nsec);
|
|
||||||
printf("The total amount of time spent for %zu function calls: %lf seconds\n", benchmarking_amount,time);
|
|
||||||
double average = time / benchmarking_amount;
|
|
||||||
printf("Average time per function: %lf seconds\n", average);
|
|
||||||
|
|
||||||
free(tempArr);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned tests(void) {
|
|
||||||
|
|
||||||
printf("Doing testing\n\n");
|
|
||||||
|
|
||||||
printf("\n\n\nTest 1: Default image, coloured\n");
|
|
||||||
float complex start = -2.0f - 0.5f*I;
|
|
||||||
size_t width = 1920;
|
|
||||||
size_t height = 1080;
|
|
||||||
float resolution = 0.001f;
|
|
||||||
int n = 200;
|
|
||||||
_Bool colored = true;
|
|
||||||
|
|
||||||
printf("Start: %f%+fi\n", crealf(start), cimagf(start));
|
|
||||||
printf("Width: %li\n",width);
|
|
||||||
printf("Height: %li\n", height);
|
|
||||||
printf("Resolution: %f\n", resolution);
|
|
||||||
printf("Iterations: %i\n", n);
|
|
||||||
printf("Colored: %s\n", colored ? "true" : "false");
|
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i < NUMBER_OF_VERSIONS;i++) {
|
|
||||||
printf("\n\n");
|
|
||||||
benchmarking(TESTING_AMOUNT,i,start, width, height, resolution, n, colored);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n\n\nTest 2: Ultra high resolution low iterations\n");
|
|
||||||
start = -2.0f - 0.5f*I;
|
|
||||||
width = 7680;
|
|
||||||
height = 4320;
|
|
||||||
resolution = 0.001f;
|
|
||||||
n = 5;
|
|
||||||
|
|
||||||
printf("Start: %f%+fi\n", crealf(start), cimagf(start));
|
|
||||||
printf("Width: %li\n",width);
|
|
||||||
printf("Height: %li\n", height);
|
|
||||||
printf("Resolution: %f\n", resolution);
|
|
||||||
printf("Iterations: %i\n", n);
|
|
||||||
printf("Colored: %s\n", colored ? "true" : "false");
|
|
||||||
|
|
||||||
for(int i = 0; i < NUMBER_OF_VERSIONS; i++) {
|
|
||||||
printf("\n\n");
|
|
||||||
benchmarking(TESTING_AMOUNT,i,start, width, height, resolution, n, colored);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n\n\nTest 3: Zoomed on fractal edge\n");
|
|
||||||
start = -1.431f - 0.250f*I;
|
|
||||||
width = 1024;
|
|
||||||
height = 1024;
|
|
||||||
resolution = 0.0005f;
|
|
||||||
n = 3000;
|
|
||||||
|
|
||||||
printf("Start: %f%+fi\n", crealf(start), cimagf(start));
|
|
||||||
printf("Width: %li\n",width);
|
|
||||||
printf("Height: %li\n", height);
|
|
||||||
printf("Resolution: %f\n", resolution);
|
|
||||||
printf("Iterations: %i\n", n);
|
|
||||||
printf("Colored: %s\n", colored ? "true" : "false");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i < NUMBER_OF_VERSIONS; i++) {
|
|
||||||
printf("\n\n");
|
|
||||||
benchmarking(TESTING_AMOUNT,i,start, width, height, resolution, n, colored);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
printf("\nTest 4: Pure Black\n");
|
|
||||||
start = 0;
|
|
||||||
width = 1920;
|
|
||||||
height = 1080;
|
|
||||||
resolution = 0.00001f;
|
|
||||||
n = 1000;
|
|
||||||
|
|
||||||
printf("Start: %f%+fi\n", crealf(start), cimagf(start));
|
|
||||||
printf("Width: %li\n",width);
|
|
||||||
printf("Height: %li\n", height);
|
|
||||||
printf("Resolution: %f\n", resolution);
|
|
||||||
printf("Iterations: %i\n", n);
|
|
||||||
printf("Colored: %s\n", colored ? "true" : "false");
|
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i < NUMBER_OF_VERSIONS; i++) {
|
|
||||||
printf("\n\n");
|
|
||||||
benchmarking(TESTING_AMOUNT,i,start, width, height, resolution, n, colored);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkInputs(_Bool n,_Bool r,_Bool o,_Bool d,_Bool s) {
|
|
||||||
if (!n)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Input n not given.\n");
|
|
||||||
}
|
|
||||||
if (!r)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Input r not given.\n");
|
|
||||||
}
|
|
||||||
if (!o)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Input o not given.\n");
|
|
||||||
}
|
|
||||||
if (!d)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Input d not given.\n");
|
|
||||||
}
|
|
||||||
if (!s)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Input s not given.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Example test command
|
// Example test command
|
||||||
// ./project -s -2.0,-1.5 -d 1200,900 -r 0.003 -n 256 -o tricorn.bmp -C
|
// ./project -s -2.0,-1.5 -d 1200,900 -r 0.003 -n 256 -o tricorn.bmp -C
|
||||||
@@ -427,24 +264,23 @@ int main(int argc, char** argv)
|
|||||||
opt_long = getopt_long(argc,argv,optstring, long_options, NULL);
|
opt_long = getopt_long(argc,argv,optstring, long_options, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
float complex complexA = (starting_point_real + starting_point_imaginary*I);
|
|
||||||
|
// Run
|
||||||
|
float complex start = (starting_point_real + starting_point_imaginary*I);
|
||||||
int bytesPerColour = colored ? 3 : 1;
|
int bytesPerColour = colored ? 3 : 1;
|
||||||
|
|
||||||
ssize_t absolute_height = height >= 0 ? height : height * - 1;
|
ssize_t absolute_height = height >= 0 ? height : height * - 1;
|
||||||
unsigned char *tempArr = malloc(width*absolute_height*bytesPerColour);// allocate image array on the heap to support large images as the stack is usually only 8 MB big
|
unsigned char *imageArr = malloc(width*absolute_height*bytesPerColour);// allocate image array on the heap to support large images as the stack is usually only 8 MB big
|
||||||
if(tempArr == NULL) {
|
|
||||||
|
if(imageArr == NULL)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
|
||||||
|
|
||||||
if (will_test)
|
if (will_test)
|
||||||
{
|
|
||||||
return tests() ? EXIT_FAILURE : EXIT_SUCCESS;
|
return tests() ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
if (!(nGiven && rGiven && oGiven && dGiven && sGiven))
|
if (!(nGiven && rGiven && oGiven && dGiven && sGiven))
|
||||||
{
|
{
|
||||||
checkInputs(nGiven,rGiven,oGiven,dGiven,sGiven);
|
checkInputs(nGiven,rGiven,oGiven,dGiven,sGiven);
|
||||||
free(tempArr);
|
free(imageArr);
|
||||||
free(output_data);
|
free(output_data);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -452,8 +288,8 @@ int main(int argc, char** argv)
|
|||||||
if (will_benchmark)
|
if (will_benchmark)
|
||||||
{
|
{
|
||||||
printf("\nDoing benchmarking. No images will be created\n");
|
printf("\nDoing benchmarking. No images will be created\n");
|
||||||
benchmarking(amount_function_called,version_to_use,complexA,width,height,resolution,n,colored);
|
benchmarking(amount_function_called,version_to_use,start,width,height,resolution,n,colored);
|
||||||
free(tempArr);
|
free(imageArr);
|
||||||
free(output_data);
|
free(output_data);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -462,31 +298,165 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
// Uses highly optimized SIMD - main implementation
|
// Uses highly optimized SIMD - main implementation
|
||||||
tricorn(complexA,width,height,resolution,n,colored,tempArr);
|
tricorn(start,width,height,resolution,n,colored,imageArr);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// Uses scalar comparison implementation
|
// Uses scalar comparison implementation
|
||||||
tricorn_V1(complexA,width,height,resolution,n,colored,tempArr);
|
tricorn_V1(start,width,height,resolution,n,colored,imageArr);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// Uses unoptimized SIMD implementation
|
// Uses unoptimized SIMD implementation
|
||||||
tricorn_V2(complexA,width,height,resolution,n,colored,tempArr);
|
tricorn_V2(start,width,height,resolution,n,colored,imageArr);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// Uses highly optimized SIMD + Threading implementation
|
// Uses highly optimized SIMD + Threading implementation
|
||||||
tricorn_V3(complexA,width,height,resolution,n,colored,tempArr);
|
tricorn_V3(start,width,height,resolution,n,colored,imageArr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_bmp(output_data,tempArr,width,height,colored);
|
save_bmp(output_data,imageArr,width,height,colored);
|
||||||
|
|
||||||
free(output_data);
|
free(output_data);
|
||||||
free(tempArr);
|
free(imageArr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void benchmarking(size_t benchmarking_amount, int version_to_use, float complex complexA, size_t width, ssize_t height, float resolution, unsigned n, _Bool colored) {
|
||||||
|
struct timespec start;
|
||||||
|
struct timespec end;
|
||||||
|
void (*tricorn_implementation)(float complex, size_t, ssize_t, float, unsigned, _Bool, unsigned char*);
|
||||||
|
|
||||||
|
unsigned int bytePerColor = colored ? 3 : 1;
|
||||||
|
unsigned char *tempArr = malloc(width*height*bytePerColor);
|
||||||
|
if(tempArr == NULL) {
|
||||||
|
fprintf(stderr,"Could not allocate memory for buffer");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (version_to_use)
|
||||||
|
{
|
||||||
|
case 0: // Uses highly optimized SIMD and threaded version / main implementation
|
||||||
|
printf("Benchmarking V0 - highly optimized SIMD\n");
|
||||||
|
tricorn_implementation = tricorn;
|
||||||
|
break;
|
||||||
|
case 1: // Uses unoptimised scalar comparison implementation
|
||||||
|
printf("Benchmarking V1 - scalar comparison implementation\n");
|
||||||
|
tricorn_implementation = tricorn_V1;
|
||||||
|
break;
|
||||||
|
case 2: // Uses optimized SISD implementation
|
||||||
|
printf("Benchmarking V2 - unoptimized SIMD implementation\n");
|
||||||
|
tricorn_implementation = tricorn_V2;
|
||||||
|
break;
|
||||||
|
case 3: // Uses unoptimized SIMD implementation
|
||||||
|
printf("Benchmarking V3 - highly optimized SIMD + Threading implementation\n");
|
||||||
|
tricorn_implementation = tricorn_V3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"Invalid version to use: V%d. Available versions are : V0,V1,V2,V3,V4,V5\n",version_to_use);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
for (size_t i = 0; i < benchmarking_amount; i++)
|
||||||
|
{
|
||||||
|
tricorn_implementation(complexA,width,height,resolution,n,colored,tempArr);
|
||||||
|
}
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
|
|
||||||
|
double time = end.tv_sec- start.tv_sec + 1e-9 * (end.tv_nsec- start.tv_nsec);
|
||||||
|
printf("The total amount of time spent for %zu function calls: %lf seconds\n", benchmarking_amount,time);
|
||||||
|
double average = time / benchmarking_amount;
|
||||||
|
printf("Average time per function: %lf seconds\n", average);
|
||||||
|
|
||||||
|
free(tempArr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_benchmarks(float complex start,size_t width, size_t height,float res,int n, _Bool colored);
|
||||||
|
unsigned tests(void) {
|
||||||
|
|
||||||
|
printf("Doing testing\n\n");
|
||||||
|
|
||||||
|
|
||||||
|
printf("\n\n\nTest 1: Default image, coloured\n");
|
||||||
|
float complex start = -2.0f - 0.5f*I;
|
||||||
|
size_t width = 1920;
|
||||||
|
size_t height = 1080;
|
||||||
|
float res = 0.001f;
|
||||||
|
int n = 200;
|
||||||
|
_Bool colored = true;
|
||||||
|
run_benchmarks(start,width,height,res,n,colored);
|
||||||
|
|
||||||
|
|
||||||
|
printf("\n\n\nTest 2: Ultra high resolution low iterations\n");
|
||||||
|
start = -2.0f - 0.5f*I;
|
||||||
|
width = 7680;
|
||||||
|
height = 4320;
|
||||||
|
res = 0.001f;
|
||||||
|
n = 5;
|
||||||
|
run_benchmarks(start,width,height,res,n,colored);
|
||||||
|
|
||||||
|
|
||||||
|
printf("\n\n\nTest 3: Zoomed on fractal edge\n");
|
||||||
|
start = -1.431f - 0.250f*I;
|
||||||
|
width = 1024;
|
||||||
|
height = 1024;
|
||||||
|
res = 0.0005f;
|
||||||
|
n = 3000;
|
||||||
|
run_benchmarks(start,width,height,res,n,colored);
|
||||||
|
|
||||||
|
|
||||||
|
printf("\nTest 4: Pure Black\n");
|
||||||
|
start = 0;
|
||||||
|
width = 1920;
|
||||||
|
height = 1080;
|
||||||
|
res = 0.00001f;
|
||||||
|
n = 1000;
|
||||||
|
run_benchmarks(start,width,height,res,n,colored);
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void run_benchmarks(float complex start,size_t width, size_t height,float res,int n, _Bool colored){
|
||||||
|
printf("Start: %f%+fi\n", crealf(start), cimagf(start));
|
||||||
|
printf("Width: %li\n",width);
|
||||||
|
printf("Height: %li\n", height);
|
||||||
|
printf("Resolution: %f\n", res);
|
||||||
|
printf("Iterations: %i\n", n);
|
||||||
|
printf("Colored: %s\n", colored ? "true" : "false");
|
||||||
|
for(int i = 0; i < NUMBER_OF_VERSIONS;i++) {
|
||||||
|
printf("\n\n");
|
||||||
|
benchmarking(TESTING_AMOUNT,i,start, width, height, res, n, colored);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkInputs(_Bool n,_Bool r,_Bool o,_Bool d,_Bool s) {
|
||||||
|
if (!n)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Input n not given.\n");
|
||||||
|
}
|
||||||
|
if (!r)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Input r not given.\n");
|
||||||
|
}
|
||||||
|
if (!o)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Input o not given.\n");
|
||||||
|
}
|
||||||
|
if (!d)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Input d not given.\n");
|
||||||
|
}
|
||||||
|
if (!s)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Input s not given.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void save_bmp(const char *filename, unsigned char *img, size_t width, ssize_t height,_Bool color) {
|
void save_bmp(const char *filename, unsigned char *img, size_t width, ssize_t height,_Bool color) {
|
||||||
// Open a file at the filepath given as a stream in the program
|
// Open a file at the filepath given as a stream in the program
|
||||||
|
|||||||
Reference in New Issue
Block a user