Améliorer la vitesse du fonction donnant un nombre aléatoire

Améliorer la vitesse du fonction donnant un nombre aléatoire - C++ - Programmation

Marsh Posté le 14-03-2007 à 14:55:26    

Bonjour,
 
j'ai écrit cette fonction pour obtenir un nombre aléatoire entre min et max inclus.

Code :
  1. //Tirage aleatoire d'un nombre
  2. int hasard(int min, int max){
  3.   return (min + (rand() % (max - min + 1)));
  4. }


 
Cette fonction est utilisé des milliers de fois dans un programme.
Le lancement du mon programme met 17secondes pour afficher les résultats.
 
Je voudrais donc essayer d'améliorer cette fonction pour essayer de la rendre plus rapide.
 
Quelqu'un aurait-il une solution ?
 
Merci

Reply

Marsh Posté le 14-03-2007 à 14:55:26   

Reply

Marsh Posté le 14-03-2007 à 22:10:34    

A première vue, je vois deux solutions:
1. inline
2. écrire une fonction rand customisée plus rapide et qui t'évite le modulo supplémentaire (car rand fait déjà probablement un modulo, jette un oeil au code source de la fonction).
Voir Numerical Recipes pour des rand rapides et fiables.


Message édité par el muchacho le 14-03-2007 à 22:10:51
Reply

Marsh Posté le 14-03-2007 à 22:11:11    

ou utiliser boost::randomizer avec une implantation du lagged_fibonacci ou d'un mersenne_twister.

Reply

Marsh Posté le 14-03-2007 à 22:12:20    

C'est rapide le Mersenne twister ?

Reply

Marsh Posté le 14-03-2007 à 22:44:31    

Accessoirement, cette facon de tirer un nombre au hasard ne serait-elle pas un peu fausse ? (Je veux dire, pas equiprobable)

Reply

Marsh Posté le 15-03-2007 à 09:11:04    

el muchacho a écrit :

C'est rapide le Mersenne twister ?


Assez, j'aipas les chiffres en têtes mais devrait y avoir des infos là :
http://www.math.sci.hiroshima-u.ac [...] -lang.html

Reply

Marsh Posté le 15-03-2007 à 10:40:59    

MT fonctionne par burst (lors du remplissage du pool), ce qui peut être inacceptable.
Il y a d'autres solutions, pas forcément meilleures qualitativement ou franchement plus rapides, n'ayant pas de telles contraintes.
 
Voir par exemple George Marsaglia, "Seeds for random number generators" http://portal.acm.org/citation.cfm [...] EN=6184618
 
Numerical Recipes est à éviter de toute urgence.


Message édité par tbp le 15-03-2007 à 10:43:42
Reply

Marsh Posté le 16-03-2007 à 09:27:14    

WTF ?

Reply

Marsh Posté le 16-03-2007 à 09:36:24    

Mersenne twister fonctionne en rafale: les valeurs viennent d'un tampon qu'il faut remplir périodiquement. En moyenne c'est rapide, mais il y a des pointes d'activité frénétique. { jargon ftw }

Message cité 1 fois
Message édité par tbp le 16-03-2007 à 09:42:58
Reply

Marsh Posté le 16-03-2007 à 11:25:46    

lasvegastheking a écrit :

Bonjour,
 
j'ai écrit cette fonction pour obtenir un nombre aléatoire entre min et max inclus.

Code :
  1. //Tirage aleatoire d'un nombre
  2. int hasard(int min, int max){
  3.   return (min + (rand() % (max - min + 1)));
  4. }


 
Cette fonction est utilisé des milliers de fois dans un programme.
Le lancement du mon programme met 17secondes pour afficher les résultats.
 
Je voudrais donc essayer d'améliorer cette fonction pour essayer de la rendre plus rapide.
 
Quelqu'un aurait-il une solution ?
 
Merci

Se poser les vrais questions : si tu as besoin de faire 17s d'appels à hasard(), t'es mal barré. Avec un CPU actuel, tu dois pouvoir faire un nombre très élevé d'appel chaque seconde. Ca veut dire que rand() va wrapper plusieurs fois. Donc que tes données aléatoires sont de très mauvaises qualité.
 
Change de générateur. Prend en un meilleur et un plus rapide. Voir un bourrin read(/dev/urandom, data, n);
 
J'imagine le for (;;) data[i] = hasard(x, y);, bonjour le carton, avec n'importe quelle fonction.
 
 

Reply

Marsh Posté le 16-03-2007 à 11:25:46   

Reply

Marsh Posté le 17-03-2007 à 08:20:54    

tbp a écrit :

Mersenne twister fonctionne en rafale: les valeurs viennent d'un tampon qu'il faut remplir périodiquement. En moyenne c'est rapide, mais il y a des pointes d'activité frénétique. { jargon ftw }


J'avais pensé à bufferiser les valeurs. Mais ma question portait sur ton commentaire sur les Numerical Recipes.

Reply

Marsh Posté le 17-03-2007 à 12:00:50    

Mille pardons.
Mon édition du Numerical Recipes in C est particulièrement poussiéreuse, mais je ne crois pas qu'ils aient récemment résolu la principale critique qu'on leur adresse: la fiabilité.

Reply

Marsh Posté le 17-03-2007 à 13:05:55    

lasvegastheking a écrit :

Bonjour,
 
j'ai écrit cette fonction pour obtenir un nombre aléatoire entre min et max inclus.

Code :
  1. //Tirage aleatoire d'un nombre
  2. int hasard(int min, int max){
  3.   return (min + (rand() % (max - min + 1)));
  4. }


 
Cette fonction est utilisé des milliers de fois dans un programme.
Le lancement du mon programme met 17secondes pour afficher les résultats.
 
Je voudrais donc essayer d'améliorer cette fonction pour essayer de la rendre plus rapide.
 
Quelqu'un aurait-il une solution ?
 
Merci


 
Je ne sais pas comment améliorer la vitesse... mais en tout cas on peut améliorer la distribution aléatoire en remplaçant par

return (int)(min + (rand() / (double)RAND_MAX * (max - min + 1)));


 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 17-03-2007 à 20:37:38    

tbp a écrit :

Mille pardons.
Mon édition du Numerical Recipes in C est particulièrement poussiéreuse, mais je ne crois pas qu'ils aient récemment résolu la principale critique qu'on leur adresse: la fiabilité.


Bah, il y a eu des errata eu fur et à mesure des éditions. C'est plutôt fiable dans l'ensemble, je pense, mais c'est sûr que ce n'est pas un package boîte noire complet comme IMSL et NAG. C'est d'ailleurs l'un des principes du livre, qui est que l'utilisateur sache ce qu'il fait. Pour moi, le principal pb des NR est que ce n'est pas ce qu'il y a de plus performant ni de plus facile à utiliser, outre le fait que le code reste assez dégueu (très fortran). Mais cette critique ne s'applique pas au chapitre sur le RNG.
Les algos présentés sont quand même assez performants en moyenne, en tout cas plus que ce qu'on peut pondre soi-même dans je dirais 90% des cas.

 

Le grand mérite de ce livre est de mettre à portée de non-spécialistes des algos jusque-là réservés aux spécialistes, et ce dans un vaste domaine de l'analyse numérique. Après libre à soi d'aller plus loin. En ce qui me concerne, tout le peu que je sais dans ce domaine, je le dois à ce livre. A l'époque, dans les années 80, les librairies numériques performantes et en libre accès se faisaient plutôt rares, voire étaient inexistantes. Je me souviens qu'on voyait de temps en temps des articles et des livres écrits par des programmeurs du dimanche (souvent des professeurs de lycée ou de math sup), en Turbo Pascal ou Turbo Basic, qui pour résoudre une équation de Laplace, qui pour trouver les zéros d'une fonction. Ca me fascinait et je les implémentais toujours. Mais les méthodes employées étaient très basiques et d'une lenteur frustrante (ahhh, la visualisation d'un champs potentiel qui s'affichait ligne par ligne au bout de N itérations :love:, même en compilé, fallait pas être pressé). Aujourd'hui, les mêmes programment en C++ et avec des algos bcp plus performants qu'avant. NR est passé par là, et a comblé un vide significatif, et ce de manière assez magistrale, je dois dire.

 

Je me souviens d'un gars qui avait fait une lib d'imagerie numérique (à l'époque où je bossais sur un système d'information géographique) et qui avait codé sa FFT à la main. Il se plaignait des perfs: 45s pour une image. La semaine suivante, il revenait tout content parce qu'il avait divisé son temps par 3 ou 4 grâce à des astuces d'optimisation. Alors je lui ai filé le site des NR, et là, il est revenu tout vert en me disant que c'était tombé à 3s. J'étais pas vraiment surpris, même si avec FFTW, il aurait sans doute fait encore mieux.

 

Désolé pour le "My life".


Message édité par el muchacho le 18-03-2007 à 10:47:53
Reply

Marsh Posté le 23-03-2007 à 11:04:10    

lasvegastheking a écrit :

Bonjour,
 
j'ai écrit cette fonction pour obtenir un nombre aléatoire entre min et max inclus.

Code :
  1. //Tirage aleatoire d'un nombre
  2. int hasard(int min, int max){
  3.   return (min + (rand() % (max - min + 1)));
  4. }


 
Cette fonction est utilisé des milliers de fois dans un programme.
Le lancement du mon programme met 17secondes pour afficher les résultats.
 
Je voudrais donc essayer d'améliorer cette fonction pour essayer de la rendre plus rapide.
 
Quelqu'un aurait-il une solution ?
 
Merci


 
man srand :
 
             "If  you want to generate a random integer between 1 and 10, you
              should always do it by using high-order bits, as in
 
                     j=1+(int) (10.0*rand()/(RAND_MAX+1.0));
 
              and never by anything resembling
 
                     j=1+(rand() % 10);
 
              (which uses lower-order bits)."
 
 

Reply

Marsh Posté le 23-03-2007 à 19:06:42    

in_your_phion a écrit :

man srand :
 
             "If  you want to generate a random integer between 1 and 10, you
              should always do it by using high-order bits, as in
 
                     j=1+(int) (10.0*rand()/(RAND_MAX+1.0));
 
              and never by anything resembling
 
                     j=1+(rand() % 10);
 
              (which uses lower-order bits)."


 
Mouais... t'as juste 6 jours de retard... :heink:


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 23-03-2007 à 21:31:28    

Sve@r a écrit :

Mouais... t'as juste 6 jours de retard... :heink:

 

non car ma réference, c'est du béton  :o c'est d'ailleurs etonnant que personne n'ai songé à faire/indiquer ça dès le départ, comme quoi

Message cité 1 fois
Message édité par in_your_phion le 23-03-2007 à 21:33:52
Reply

Marsh Posté le 23-03-2007 à 22:06:36    

C'est les Numerical Recipes, pardi.

Reply

Marsh Posté le 24-03-2007 à 02:03:52    

el muchacho a écrit :

C'est les Numerical Recipes, pardi.


 
mouaaaaaaaais

Reply

Marsh Posté le 26-03-2007 à 21:22:31    

in_your_phion a écrit :

c'est d'ailleurs etonnant que personne n'ai songé à faire/indiquer ça dès le départ, comme quoi


Je l'ai indiqué le 17 mars !!!  :o  


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed