Added lookup table for the colors for optimization

Made test output a bit prettier
Made tests run function 10 times for higher accuracy
This commit is contained in:
Nikola
2026-07-14 00:15:07 +02:00
parent 1318798ac2
commit f9bd827b2c
5 changed files with 96 additions and 23 deletions
+42 -8
View File
@@ -76,13 +76,47 @@ unsigned tests(void) {
} }
printf("\nTest 1: Default image, not coloured\n"); printf("\nTest 1: Default image, not coloured\n");
benchmarking(3,0,-2.0f - 0.5f*I, width, height, 0.001f, 200, false, tempArrNotColored); printf("\n\n");
printf("\nTest 2: Default image, coloured\n"); benchmarking(10,0,-2.0f - 0.5f*I, width, height, 0.001f, 200, false, tempArrNotColored);
benchmarking(3,0,-2.0f - 0.5f*I, width, height, 0.001f, 200, true, tempArrColored); printf("\n\n");
printf("\nTest 3: High iteration count\n"); benchmarking(10,1,-2.0f - 0.5f*I, width, height, 0.001f, 200, false, tempArrNotColored);
benchmarking(3,0,-2.0f - 0.5f*I, width, height, 0.001f, 5000, false, tempArrNotColored); printf("\n\n");
printf("\nTest 4: Zoomed image\n"); benchmarking(10,2,-2.0f - 0.5f*I, width, height, 0.001f, 200, false, tempArrNotColored);
benchmarking(3,0,-0.5f - 0.5f*I, 1024, 1024, 0.0005f, 500, false, tempArrNotColored); printf("\n\n");
benchmarking(10,3,-2.0f - 0.5f*I, width, height, 0.001f, 200, false, tempArrNotColored);
printf("\n\n\nTest 2: Default image, coloured\n");
printf("\n\n");
benchmarking(10,0,-2.0f - 0.5f*I, width, height, 0.001f, 200, true, tempArrColored);
printf("\n\n");
benchmarking(10,1,-2.0f - 0.5f*I, width, height, 0.001f, 200, true, tempArrColored);
printf("\n\n");
benchmarking(10,2,-2.0f - 0.5f*I, width, height, 0.001f, 200, true, tempArrColored);
printf("\n\n");
benchmarking(10,3,-2.0f - 0.5f*I, width, height, 0.001f, 200, true, tempArrColored);
printf("\n\n\nTest 3: High iteration count\n");
printf("\n\n");
benchmarking(10,0,-2.0f - 0.5f*I, width, height, 0.001f, 5000, false, tempArrNotColored);
printf("\n\n");
benchmarking(10,1,-2.0f - 0.5f*I, width, height, 0.001f, 5000, false, tempArrNotColored);
printf("\n\n");
benchmarking(10,2,-2.0f - 0.5f*I, width, height, 0.001f, 5000, false, tempArrNotColored);
printf("\n\n");
benchmarking(10,3,-2.0f - 0.5f*I, width, height, 0.001f, 5000, false, tempArrNotColored);
printf("\n\n\nTest 4: Zoomed image\n");
printf("\n\n");
benchmarking(10,0,-0.5f - 0.5f*I, 1024, 1024, 0.0005f, 500, false, tempArrNotColored);
printf("\n\n");
benchmarking(10,1,-0.5f - 0.5f*I, 1024, 1024, 0.0005f, 500, false, tempArrNotColored);
printf("\n\n");
benchmarking(10,2,-0.5f - 0.5f*I, 1024, 1024, 0.0005f, 500, false, tempArrNotColored);
printf("\n\n");
benchmarking(10,3,-0.5f - 0.5f*I, 1024, 1024, 0.0005f, 500, false, tempArrNotColored);
free(tempArrColored); free(tempArrColored);
free(tempArrNotColored); free(tempArrNotColored);
@@ -217,7 +251,7 @@ int main(int argc, char** argv)
if (version_to_use < 0 || version_to_use > 5 || end == optarg || *end != '\0') if (version_to_use < 0 || version_to_use > 5 || end == optarg || *end != '\0')
{ {
fprintf(stderr,"Invalid version to use: V%s. Available versions are : V0,V1,V2,V3,V4,V5\n", optarg); fprintf(stderr,"Invalid version to use: V%s. Available versions are : V0,V1,V2,V3\n", optarg);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf("version is %d\n", version_to_use); printf("version is %d\n", version_to_use);
+12 -3
View File
@@ -16,6 +16,15 @@ static unsigned converge(float c_real, float c_imag, unsigned n);
*/ */
void tricorn(float complex start, size_t width, ssize_t height, float res, unsigned n, _Bool color, unsigned char* img){ void tricorn(float complex start, size_t width, ssize_t height, float res, unsigned n, _Bool color, unsigned char* img){
int bytesPerColor = color ? 3 : 1; int bytesPerColor = color ? 3 : 1;
unsigned char color_lookup_table[256][3];
if(color) {
for (int i = 0; i < 256; i++) {
color_lookup_table[i][0] = (unsigned char)((i * 3) % 255);
color_lookup_table[i][1] = (unsigned char)((i * 2) % 255);
color_lookup_table[i][2] = (unsigned char)((i * 5) % 255);
}
}
// Absolute height for iteration purposes // Absolute height for iteration purposes
ssize_t actual_height = height < 0 ? (ssize_t)(-height) : height; ssize_t actual_height = height < 0 ? (ssize_t)(-height) : height;
@@ -86,9 +95,9 @@ void tricorn(float complex start, size_t width, ssize_t height, float res, unsig
img[position] = value; img[position] = value;
} }
else { else {
img[position] = ((value*3) % 255); img[position] = color_lookup_table[value][0];
img[position + 1] = ((value*2) % 255); img[position + 1] = color_lookup_table[value][1];
img[position + 2] = ((value*5) % 255); img[position + 2] = color_lookup_table[value][2];
} }
} }
c_real_vector = _mm_add_ps(c_real_vector,_mm_set1_ps(four_res)); c_real_vector = _mm_add_ps(c_real_vector,_mm_set1_ps(four_res));
+13 -3
View File
@@ -15,6 +15,16 @@ static unsigned converge(float c_real, float c_imag, unsigned n);
*/ */
void tricorn_V1(float complex start, size_t width, ssize_t height, float res, unsigned n, _Bool color, unsigned char* img){ void tricorn_V1(float complex start, size_t width, ssize_t height, float res, unsigned n, _Bool color, unsigned char* img){
int bytesPerColor = color ? 3 : 1; int bytesPerColor = color ? 3 : 1;
unsigned char color_lookup_table[256][3];
if(color) {
for (int i = 0; i < 256; i++) {
color_lookup_table[i][0] = (unsigned char)((i * 3) % 255);
color_lookup_table[i][1] = (unsigned char)((i * 2) % 255);
color_lookup_table[i][2] = (unsigned char)((i * 5) % 255);
}
}
// Absolute height for iteration purposes // Absolute height for iteration purposes
ssize_t actual_height = height > 0 ? height : (ssize_t)(-height); ssize_t actual_height = height > 0 ? height : (ssize_t)(-height);
@@ -44,9 +54,9 @@ void tricorn_V1(float complex start, size_t width, ssize_t height, float res, un
img[position] = value; img[position] = value;
} }
else{ // Temporary colors with random multipliers else{ // Temporary colors with random multipliers
img[position] = ((value*3) % 255); img[position] = color_lookup_table[value][0];
img[position + 1] = ((value*2) % 255) ; img[position + 1] = color_lookup_table[value][1];
img[position + 2] = ((value*5) % 255); img[position + 2] = color_lookup_table[value][2];
} }
position += bytesPerColor; position += bytesPerColor;
+12 -3
View File
@@ -16,6 +16,15 @@ static unsigned converge(float c_rea, float c_imag, unsigned n);
*/ */
void tricorn_V2(float complex start, size_t width, ssize_t height, float res, unsigned n, _Bool color, unsigned char* img){ void tricorn_V2(float complex start, size_t width, ssize_t height, float res, unsigned n, _Bool color, unsigned char* img){
int bytesPerColor = color ? 3 : 1; int bytesPerColor = color ? 3 : 1;
unsigned char color_lookup_table[256][3];
if(color) {
for (int i = 0; i < 256; i++) {
color_lookup_table[i][0] = (unsigned char)((i * 3) % 255);
color_lookup_table[i][1] = (unsigned char)((i * 2) % 255);
color_lookup_table[i][2] = (unsigned char)((i * 5) % 255);
}
}
// Absolute height for iteration purposes // Absolute height for iteration purposes
ssize_t actual_height = height < 0 ? (ssize_t)(-height) : height; ssize_t actual_height = height < 0 ? (ssize_t)(-height) : height;
@@ -83,9 +92,9 @@ void tricorn_V2(float complex start, size_t width, ssize_t height, float res, un
img[position] = value; img[position] = value;
} }
else { else {
img[position] = ((value*3) % 255); img[position] = color_lookup_table[value][0];
img[position + 1] = ((value*2) % 255); img[position + 1] = color_lookup_table[value][1];
img[position + 2] = ((value*5) % 255); img[position + 2] = color_lookup_table[value][2];
} }
} }
} }
+17 -6
View File
@@ -22,6 +22,10 @@ typedef struct {
const_args* consts; const_args* consts;
} compute_args; } compute_args;
unsigned char color_lookup_table[256][3];
/** /**
* @brief Generates a Tricorn fractal image using an optimized SIMD + Threading implementation. * @brief Generates a Tricorn fractal image using an optimized SIMD + Threading implementation.
* @param start The starting complex coordinate (bottom-left or top-left depending on height sign). * @param start The starting complex coordinate (bottom-left or top-left depending on height sign).
@@ -33,6 +37,13 @@ typedef struct {
* @param img Pointer to the pre-allocated memory buffer where the bitmap data will be stored. * @param img Pointer to the pre-allocated memory buffer where the bitmap data will be stored.
*/ */
void tricorn_V3(float complex start, size_t width, ssize_t height, float res, unsigned n, _Bool color, unsigned char* img){ void tricorn_V3(float complex start, size_t width, ssize_t height, float res, unsigned n, _Bool color, unsigned char* img){
if(color) {
for (int i = 0; i < 256; i++) {
color_lookup_table[i][0] = (unsigned char)((i * 3) % 255);
color_lookup_table[i][1] = (unsigned char)((i * 2) % 255);
color_lookup_table[i][2] = (unsigned char)((i * 5) % 255);
}
}
const ssize_t min_rows_per_thread = 10; const ssize_t min_rows_per_thread = 10;
const _Bool flipped = height < 0; const _Bool flipped = height < 0;
@@ -153,9 +164,9 @@ static void* compute(void * vargs){
c->img[position] = value; c->img[position] = value;
} }
else { else {
c->img[position] = ((value*3) % 255); c->img[position] = color_lookup_table[value][0];
c->img[position + 1] = ((value*2) % 255); c->img[position + 1] = color_lookup_table[value][1];
c->img[position + 2] = ((value*5) % 255); c->img[position + 2] = color_lookup_table[value][2];
} }
} }
c_real_vector = _mm_add_ps(c_real_vector,_mm_set1_ps(four_res)); c_real_vector = _mm_add_ps(c_real_vector,_mm_set1_ps(four_res));
@@ -171,9 +182,9 @@ static void* compute(void * vargs){
c->img[position] = value; c->img[position] = value;
} }
else { else {
c->img[position] = ((value*3) % 255); c->img[position] = color_lookup_table[value][0];
c->img[position + 1] = ((value*2) % 255); c->img[position + 1] = color_lookup_table[value][1];
c->img[position + 2] = ((value*5) % 255); c->img[position + 2] = color_lookup_table[value][2];
} }
} }
c_imag += vertical_step; c_imag += vertical_step;