From 4a6d8cb9c14285cb7a30fe9c6eba87962f4b33fb Mon Sep 17 00:00:00 2001 From: Yashar Alan Zenker Date: Fri, 17 Jul 2026 12:22:23 +0200 Subject: [PATCH] Cleanup: Improved main file readablilty and redundant code --- Implementierung/main.c | 338 +++++++++++++++++++---------------------- 1 file changed, 154 insertions(+), 184 deletions(-) diff --git a/Implementierung/main.c b/Implementierung/main.c index 0189898..b184bbd 100644 --- a/Implementierung/main.c +++ b/Implementierung/main.c @@ -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 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 // ./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); } - 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; - 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 - if(tempArr == NULL) { + 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(imageArr == NULL) exit(EXIT_FAILURE); - } - + if (will_test) - { return tests() ? EXIT_FAILURE : EXIT_SUCCESS; - } - + if (!(nGiven && rGiven && oGiven && dGiven && sGiven)) { checkInputs(nGiven,rGiven,oGiven,dGiven,sGiven); - free(tempArr); + free(imageArr); free(output_data); return EXIT_FAILURE; } @@ -452,8 +288,8 @@ int main(int argc, char** argv) if (will_benchmark) { printf("\nDoing benchmarking. No images will be created\n"); - benchmarking(amount_function_called,version_to_use,complexA,width,height,resolution,n,colored); - free(tempArr); + benchmarking(amount_function_called,version_to_use,start,width,height,resolution,n,colored); + free(imageArr); free(output_data); return EXIT_SUCCESS; } @@ -462,31 +298,165 @@ int main(int argc, char** argv) { case 0: // Uses highly optimized SIMD - main implementation - tricorn(complexA,width,height,resolution,n,colored,tempArr); + tricorn(start,width,height,resolution,n,colored,imageArr); break; case 1: // Uses scalar comparison implementation - tricorn_V1(complexA,width,height,resolution,n,colored,tempArr); + tricorn_V1(start,width,height,resolution,n,colored,imageArr); break; case 2: // Uses unoptimized SIMD implementation - tricorn_V2(complexA,width,height,resolution,n,colored,tempArr); + tricorn_V2(start,width,height,resolution,n,colored,imageArr); break; case 3: // 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; default: break; } - save_bmp(output_data,tempArr,width,height,colored); + save_bmp(output_data,imageArr,width,height,colored); free(output_data); - free(tempArr); + free(imageArr); 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) { // Open a file at the filepath given as a stream in the program