From 7da6cd803b14c8b966a377ee15289b5087ec91ea Mon Sep 17 00:00:00 2001 From: Yashar Alan Zenker Date: Sat, 4 Jul 2026 20:34:08 +0200 Subject: [PATCH] Removed redudant copy of constant arguments --- Implementierung/tricorn.c | 79 ++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/Implementierung/tricorn.c b/Implementierung/tricorn.c index 8f568f4..fdac068 100644 --- a/Implementierung/tricorn.c +++ b/Implementierung/tricorn.c @@ -3,20 +3,25 @@ static void* compute(void * args); static unsigned converge(float c_real, float c_imag, unsigned n); static size_t get_thread_count(); -typedef struct { + +// Argument structs passed to the threads for the caluclations +typedef struct{ unsigned n; _Bool color; _Bool flipped; - - float start_r; - float start_i; float res; - size_t start_row; - size_t stop_row; size_t width; unsigned char* img; +} const_args; +typedef struct { + float start_r; + float start_i; + size_t start_row; + size_t stop_row; + const_args* consts; } compute_args; + /** * @brief Generates a Tricorn fractal image using an optimized SISD implementation. * @param start The starting complex coordinate (bottom-left or top-left depending on height sign). @@ -47,6 +52,14 @@ void tricorn(float complex start, size_t width, ssize_t height, float res, unsig const float start_i = cimagf(start); const float directional_res = (flipped ? -1.0f: 1.0f)*res; + const_args* consts = malloc(sizeof(*consts)); + consts->width = width; + consts->flipped = flipped; + consts->color = color; + consts->res = res; + consts->img = img; + consts->n = n; + pthread_t threads[thread_count]; for(size_t i = 0; i < thread_count; i++){ compute_args* args = malloc(sizeof(*args)); @@ -54,12 +67,7 @@ void tricorn(float complex start, size_t width, ssize_t height, float res, unsig args->start_i =start_i-i*directional_res*y_step; args->start_row = i*y_step; args->stop_row = abs_height < (args->start_row+y_step) ? abs_height: (args->start_row+y_step); - args->width = width; - args-> flipped = flipped; - args->color = color; - args->res = res; - args->img = img; - args->n = n; + args->consts = consts; if(pthread_create(&threads[i],NULL,compute,args)){ compute(args); free(args); @@ -70,18 +78,21 @@ void tricorn(float complex start, size_t width, ssize_t height, float res, unsig pthread_join(threads[i],NULL); } + free(consts); + consts = NULL; return; } static void* compute(void * vargs){ compute_args *args = vargs; + const_args *c = args->consts; vargs = NULL; - const int bytes_per_color = args->color ? 3 : 1; + const int bytes_per_color = c->color ? 3 : 1; // Absolute height for iteration purposes - const size_t simd_width = (args->width / 4) * 4; + const size_t simd_width = (c->width / 4) * 4; float c_start_real = args->start_r; __m128 four = _mm_set1_ps(4.0f); @@ -90,20 +101,20 @@ static void* compute(void * vargs){ float c_imag = args->start_i; __m128 c_imag_vector = _mm_set1_ps(c_imag); - float four_res = 4 * args->res; - float vertical_step = (args->flipped? -1.0f: 1.0f) * args->res; + float four_res = 4 * c->res; + float vertical_step = (c->flipped? -1.0f: 1.0f) * c->res; __m128 vertical_step_vector = _mm_set1_ps(vertical_step); for(size_t y = args->start_row; y < args->stop_row;y++) { size_t x = 0; - __m128 c_real_vector = _mm_setr_ps(c_start_real,c_start_real + 1.0f*args->res,c_start_real + 2.0f*args->res, c_start_real + 3.0f*args->res); + __m128 c_real_vector = _mm_setr_ps(c_start_real,c_start_real + 1.0f*c->res,c_start_real + 2.0f*c->res, c_start_real + 3.0f*c->res); for(; x < simd_width;x += 4) { //SIMD Loop __m128 real = _mm_setzero_ps(); __m128 imag = _mm_setzero_ps(); __m128i iterations = _mm_setzero_si128(); __m128i active_mask = _mm_set1_epi32(-1); - for(unsigned i = 0; i < args->n;i++) { + for(unsigned i = 0; i < c->n;i++) { __m128 real2 = _mm_mul_ps(real,real); __m128 imag2 = _mm_mul_ps(imag,imag); @@ -127,7 +138,7 @@ static void* compute(void * vargs){ __m128i times4 = _mm_slli_epi32(mod64, 2); __m128i values = _mm_sub_epi32(_mm_set1_epi32(255), times4); - __m128i max_iter = _mm_set1_epi32(args->n); + __m128i max_iter = _mm_set1_epi32(c->n); __m128i is_max = _mm_cmpeq_epi32(iterations, max_iter); values = _mm_andnot_si128(is_max, values); @@ -136,33 +147,33 @@ static void* compute(void * vargs){ for(unsigned i = 0 ; i < 4;i++) { unsigned int value = value_array[i]; - size_t position = (y*args->width + (x+i)) * bytes_per_color; + size_t position = (y*c->width + (x+i)) * bytes_per_color; - if(!args->color) { - args->img[position] = value; + if(!c->color) { + c->img[position] = value; } else { - args->img[position] = ((value*3) % 255); - args->img[position + 1] = ((value*2) % 255); - args->img[position + 2] = ((value*5) % 255); + c->img[position] = ((value*3) % 255); + c->img[position + 1] = ((value*2) % 255); + c->img[position + 2] = ((value*5) % 255); } } c_real_vector = _mm_add_ps(c_real_vector,_mm_set1_ps(four_res)); } - for(;x < args->width; x++) { - float c_real = c_start_real + (x*args->res); - unsigned int value = converge(c_real,c_imag,args->n); + for(;x < c->width; x++) { + float c_real = c_start_real + (x*c->res); + unsigned int value = converge(c_real,c_imag,c->n); - size_t position = (y*args->width + x) * bytes_per_color; + size_t position = (y*c->width + x) * bytes_per_color; - if(!args->color) { - args->img[position] = value; + if(!c->color) { + c->img[position] = value; } else { - args->img[position] = ((value*3) % 255); - args->img[position + 1] = ((value*2) % 255); - args->img[position + 2] = ((value*5) % 255); + c->img[position] = ((value*3) % 255); + c->img[position + 1] = ((value*2) % 255); + c->img[position + 2] = ((value*5) % 255); } } c_imag -= vertical_step;