2016-02-08 1 views
0

J'ai écrit un zoom Mandelbrot en C++ mais le zoom était limité en raison de l'imprécision du point flottant. C'est pourquoi j'ai écrit le tout againg avec la bibliothèque GMP.Même fonction? fonctionne environ 10 fois plus lentement avec GMP (C++)

Mais maintenant j'ai des problèmes avec les performances. Je suis nouveau GMP alors peut-être que je viens foiré quelques petites choses:

Voici le code original:

int iterate(double xp, double yp, int iterations){ 
double length = 1; 
double x = 0; 
double y = 0; 
double r; 
for(int i = 0; i < iterations && length <= 2; i++){ 
    double xTemp = x; 
    //calculate real part 
    x = (x*x)+xp-(y*y); 
    //calculate imaginary part 
    y = 2*xTemp*y+yp; 
    //calculate lenth 
    length = sqrt(x*x+y*y); 
    r = i+1; 
} 
if(length > 2) 
    return r; 
return 0; 

}

Fonction identique aux BPF (je pense que c'est la même chose), J'ai ajouté deux variables, la température et temp2, pour stocker des valeurs pour le calcul mais cela ne devrait pas le faire 10 fois plus lent:

int iterateGMP(mpf_t xpGMP, mpf_t ypGMP, int iterations){ 
double r; 

mpf_set_default_prec (20); 

mpf_t length; 
mpf_init(length); 
mpf_set_d(length, 1); 
mpf_t x; 
mpf_init(x); 
mpf_set_d(x, 0); 
mpf_t y; 
mpf_init(y); 
mpf_set_d(y, 0); 
mpf_t xTemp; 
mpf_init(xTemp); 
mpf_t TempGMP; 
mpf_init(TempGMP); 
mpf_t Temp2GMP; 
mpf_init(Temp2GMP); 


for(int i = 0; i < iterations && mpf_cmp_ui(length, 2)<0; i++){ 
    mpf_set(xTemp, x); 

    //calculate real part 
    mpf_mul(TempGMP, x, x); 
    mpf_add(TempGMP, TempGMP, xpGMP); 
    mpf_mul(Temp2GMP, y, y); 
    mpf_sub(x, TempGMP, Temp2GMP); 

    //calculate imaginary part 
    mpf_mul(TempGMP, xTemp, y); 
    mpf_mul_ui(TempGMP, TempGMP, 2); 
    mpf_add(y, TempGMP, ypGMP); 

    //calculate length 
    mpf_mul(TempGMP, x, x); 
    mpf_mul(Temp2GMP, y, y); 
    mpf_add(TempGMP, TempGMP, Temp2GMP); 
    mpf_sqrt(length, TempGMP); 
    r = i+1; 
} 
if(mpf_cmp_ui(length, 2) > 0){ 
    return r; 
} 
return 0; 

}

J'espère que quelqu'un peut m'aider.

+2

Avez-vous activé les optimisations? Une perte de performance de 10x n'est pas totalement déraisonnable pour une bibliothèque de précision arbitraire. – nwp

+1

C'est OT, mais vous pouvez faire les deux codes plus rapidement en évitant la racine carrée. Il suffit de tester la longueur (au carré) supérieure à 4. –

+0

@nwp Comment puis-je activer l'optimisation? – Joel

Répondre

4

I a ajouté deux variables, la température et temp2, pour stocker des valeurs pour le calcul mais cela ne devrait pas le faire 10 fois plus lent

opérations sur float et double sont normalement traitées par le matériel. Alors que les opérations sur les types GMP sont gérées par la bibliothèque GMP dans le logiciel.

Les valeurs GMP nécessitent également plus de mémoire pour stocker et la mémoire est souvent le goulot d'étranglement.

+0

Le problème dans ce cas (une boucle de Mandelbrot) n'est pas la mémoire supplémentaire, c'est que le flotteur de précision prolongée est * beaucoup * plus lent que le point flottant matériel. C'est une boucle liée à la latence avec les mêmes données à plusieurs reprises. –