The code has no errors, it is just slow. It takes 1.19s to start.
How can I reduce runtime without using threads or multiple processes?
I have tried compiler optimization
(-o1, -o2 and -o3)
These did not do much.
typedef struct s_float2{
double x;
double y;
} t_float2;
static t_float2 next(t_float2 z)
{
t_float2 new;
double temp_deno;
temp_deno = 3 * (z.x * z.x + z.y * z.y) * (z.x * z.x + z.y * z.y);
new.x = ((z.x * z.x * z.x * z.x * z.x + 2 * z.x * z.x * z.x * z.y * z.y
- z.x * z.x + z.x * z.y * z.y * z.y * z.y + z.y * z.y)
/ temp_deno);
new.y = ((z.y * (z.x * z.x * z.x * z.x + 2 * z.x * z.x
* z.y * z.y + 2 * z.x + z.y * z.y * z.y * z.y))
/ temp_deno);
z.x -= new.x;
z.y -= new.y;
return (z);
}
static t_float2 find_diff(t_float2 z, t_float2 root)
{
t_float2 new;
new.x = z.x - root.x;
new.y = z.y - root.y;
return (new);
}
void init_roots(t_float2 *roots)
{
static unsigned int flag;
if (!flag)
{
roots[0] = (t_float2){1, 0};
roots[1] = (t_float2){-0.5, 0.866025403784438};
roots[2] = (t_float2){-0.5, -0.866025403784438};
flag = 1;
}
}
unsigned int checker_tolerance(t_fractal *fractal, t_float2 z,
unsigned int iterations)
{
t_float2 difference;
static t_float2 roots[3];
init_roots(&roots);
difference = find_diff(z, roots[0]);
if (fabs(difference.x) < fractal->tolerance
&& fabs(difference.y) < fractal->tolerance)
return (1);
difference = find_diff(z, roots[1]);
if (fabs(difference.x) < fractal->tolerance
&& fabs(difference.y) < fractal->tolerance)
return (1);
difference = find_diff(z, roots[2]);
if (fabs(difference.x) < fractal->tolerance
&& fabs(difference.y) < fractal->tolerance)
return (1);
return (0);
}
void calculate_newton(t_fractal *fractal)
{
t_float2 z;
unsigned int iterations;
iterations = 0;
z.x = (fractal->x / fractal->zoom) + fractal->offset_x;
z.y = (fractal->y / fractal->zoom) + fractal->offset_y;
while (iterations < fractal->max_iterations)
{
z = next(z);
if (checker_tolerance(fractal, z, iterations) == 1)
return (put_color_to_pixel(fractal, fractal->x, fractal->y,
fractal->color * iterations / 2));
++iterations;
}
put_color_to_pixel(fractal, fractal->x, fractal->y, 0x000000);
}
The github link is https://github.com/MehdiMirzaie2/fractol.
Also, if you just want the main here it is:
# include <mlx.h>
# include <stdlib.h>
# include <unistd.h>
typedef struct s_fractal
{
void *mlx;
void *window;
void *image;
void *pointer_to_image;
int bits_per_pixel;
int size_line;
int endian;
int x;
int y;
double zx;
double zy;
double cx;
double cy;
int color;
double offset_x;
double offset_y;
double zoom;
int name;
int max_iterations;
float tolerance;
} t_fractal;
static void free_and_explain(t_fractal *fractal)
{
ft_putendl_fd("Available fractals: a = mandel, b = julia, c = newton\
\n\033[1;31mASK FOR EXTRA, check your program!\033[0m", 1);
exit_fractal(fractal);
}
int draw_fractal(t_fractal *fractal, double cx, double cy)
{
fractal->x = 0;
fractal->y = 0;
while (fractal->x < SIZE)
{
while (fractal->y < SIZE)
{
if (fractal->name == 'a')
calculate_mandelbrot(fractal);
else if (fractal->name == 'b')
calculate_julia(fractal, cx, cy);
else if (fractal->name == 'c')
calculate_newton(fractal);
else
free_and_explain(fractal);
fractal->y++;
}
fractal->x++;
fractal->y = 0;
}
mlx_put_image_to_window(fractal->mlx, fractal->window, fractal->image, 0,
0);
return (0);
}
int main(int argc, char **argv)
{
t_fractal *fractal;
if (argc != 2 || argv[1][1] != '\0')
{
ft_putendl_fd("Available fractals: a = mandel, b = julia, c = newton\
\n\033[1;31mASK FOR EXTRA!\033[0m", 1);
return (0);
}
fractal = malloc(sizeof(t_fractal));
init_fractal(fractal);
init_mlx(fractal);
fractal->name = argv[1][0];
mlx_key_hook(fractal->window, key_hook, fractal);
mlx_mouse_hook(fractal->window, mouse_hook, fractal);
mlx_hook(fractal->window, 17, 0L, exit_fractal, fractal);
draw_fractal(fractal, -0.79, 0.15);
mlx_loop(fractal->mlx);
return (0);
}
```
#include
lines, and amain()
that shows how to call your function. It can really help reviewers if they are able to compile and run your program. \$\endgroup\$-o3
sets the output file name to3
, still no optimization. Hopefully you actually tried-O3
. (Also try-O3 -march=native -ffast-math
with GCC or clang, and also-fprofile-generate
/ run it /-fprofile-use
. See also Which gcc optimization flags should I use? and this for some interesting compiler options.) \$\endgroup\$main()
. Post your code (withmain()
so others may attempt to compare times. \$\endgroup\$main()
here. No need to add difficulties for reviewers who provide quality feedback at zero cost. \$\endgroup\$