Fractale de Mandelbrot
LittDev
-
LittDev -
LittDev -
Salut
J'ai programmé un petit générateur de fractales de mandelbrot avec la SDL, mais il prend beaucoup de temps pour calculer, malgré un nombre d’itérations assez faible, n'y aurait pas t-il des optimisations a faire dans le code ou des erreurs qui ralentissent le calcul ?
Pour ceux qui ne savent pas ce que c'est :
https://fr.wikipedia.org/wiki/Ensemble_de_Mandelbrot
Merci d'avance
J'ai programmé un petit générateur de fractales de mandelbrot avec la SDL, mais il prend beaucoup de temps pour calculer, malgré un nombre d’itérations assez faible, n'y aurait pas t-il des optimisations a faire dans le code ou des erreurs qui ralentissent le calcul ?
Pour ceux qui ne savent pas ce que c'est :
https://fr.wikipedia.org/wiki/Ensemble_de_Mandelbrot
#include <complex> #include <cstdlib> #include <iostream> #include <string> #include <cmath> #include <SDL/SDL.h> #define X 899 #define Y 599 using namespace std; //Structure simple pour les couleurs typedef struct { int r; int g; int b; }Color; void set_color(Color& color, int const& r, int const& g, int const& b) { color.r = r; color.g = g; color.b = b; } //Fonction gaussienne double gauss(long double const& x, long double const& var, long double const& moy) { return exp(-1*((x-moy)*(x-moy))/var); } //Calcule la couleur en fonction de l'iteration en utilisant la fonction gaussienne Color calculate_color(int const& iterations, int const& iter_max) { Color result; if(iterations == iter_max) { set_color(result,0,0,0); return result; } double temp(static_cast <double>(iterations%768)/768), var(0.1); set_color(result, static_cast <int>(256*gauss(temp,0.25*var,0.5)), static_cast <int>(256*gauss(temp,var,0.5)), static_cast <int>(256*gauss(temp,0.5*var,0.5))); return result; } //La fonction qui permet de generer les termes de la suite en fonction de cst et du nombre d'iterations maximum int mandelbrot_suite(complex <long double> const& cst, int iter_max) { complex <long double> result(0,0); for(int i(0);i<iter_max;i++) { result = result*result + cst; if(norm(result)>2) return i; } return iter_max; } int main (int argc, char** argv) { //Zoom : Nombre de pixels par unité (ex : 45000 par 1.5) long zoom = 30000; SDL_Surface* screen = SDL_SetVideoMode(X, Y, 16, SDL_HWSURFACE|SDL_DOUBLEBUF); if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) return 1; atexit(SDL_Quit); SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 255, 255, 255)); SDL_Flip(screen); bool done(false); SDL_Rect pos; pos.x = 0; pos.y = 0; pos.h = 1; pos.w = 1; while (!done) { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: done = true; break; case SDL_KEYDOWN: { if (event.key.keysym.sym == SDLK_ESCAPE) done = true; break; } } } //Transformation des points de l'ecran en nombre complexe, en fonction du zoom complex <long double> cst(static_cast <long double>(pos.x - (X+1)/2)/zoom - 0.11,static_cast <long double>(((Y+1)/2) - pos.y)/zoom + 0.895); //Calcul du nombre d'iterations int result(mandelbrot_suite(cst,768)); //Choix de la couleur Color color(calculate_color(result,768)); //Creation du pixel en fonction de la couleur choisie et de la position SDL_FillRect(screen,&pos,SDL_MapRGB(screen->format,color.r,color.g,color.b)); if(pos.x < screen->w-1) pos.x++; else if(pos.y < screen->h-1) { pos.y++; pos.x=0; } else SDL_Flip(screen); } return 0; }
Merci d'avance
1 réponse
Utilise un Profiler pour voir là où le programme passe du temps, je n'ai pas pu compiler ton code (j'utilise SDL2 et non SDL1)
Sache que c'est fortement parallélisable/vectorisable comme code, si tu veux te lancer là dedans :)
En plus, sauf si tu as besoin vraiment de précision étendue, double est bien plus rapide. Pour un GPU float sera encore plus rapide.
Sache que c'est fortement parallélisable/vectorisable comme code, si tu veux te lancer là dedans :)
En plus, sauf si tu as besoin vraiment de précision étendue, double est bien plus rapide. Pour un GPU float sera encore plus rapide.
J'ai tout changé, je suis passé à la SFML, j'ai bien revu la boucle du programme, bien factorisé le code, et j'ai trouvé des optimisations de calcul, et j'ai mainenant un resultat plutôt satisfaisant :)