RNG et multithreading

RNG et multithreading - C++ - Programmation

Marsh Posté le 28-10-2010 à 16:34:33    

Bonjour,
 
J'utilise boost::mt19937 comme RNG.
Avant de multithreader mon code je l'avait mis dans un singleton pour le seeder une seule fois pour toutes.

Code :
  1. class RandomGenerator : public boost::mt19937{
  2.     static ml::RandomGenerator m_instance;
  3.     RandomGenerator(){
  4.       seed( time(NULL) * getpid() );
  5.     }
  6.     ~RandomGenerator(){}
  7.   public:
  8.     static RandomGenerator& instance(){
  9.       return m_instance;
  10.     }
  11.   };


Maintenant je suis en train de multithreader mon code avec OPENMP, et je voudrais faire ça un peu propremment. Comme je voudrais avoir le même RNG dans tous les threads, je suis confronté au problème suivant :
L'appel est donc de la forme :

Code :
  1. boost::bernoulli_distribution<> distrib(threshold);
  2. event = distrib(RandomGenerator::instance());


sauf que j'ai cru comprendre que boost::mt19937 n'est pas thread-safe. Donc je peux avoir deux threads qui appellent le RNG en même temps et qui vont donc avoir le même résultat. Et je ne vois pas trop comment m'en sortir. En effet, ce qui devrait être locké, ce n'est pas le fait de demander l'instance du RNG, mais l'utilisation qu'en fait la distribution.
Est-ce que je vais devoir me rabattre sur un RNG par thread (comme j'utilise OpenMP je sais pas trop comment ça va être possible) ou y a-t-il un solution à ce problème ?


Message édité par Lan Wezel le 28-10-2010 à 18:19:57
Reply

Marsh Posté le 28-10-2010 à 16:34:33   

Reply

Marsh Posté le 28-10-2010 à 18:11:19    

J'ai trouvé une solution, mais je ne sais pas si c'est très propre.
Comme l'operateur () des random::distribution est template de l'Engine (RNG), j'ai réimplémenté l'operateur () du RNG en mettant une section critique.
 

Code :
  1. class RandomGenerator : public boost::mt19937{
  2.     static ml::RandomGenerator m_instance;
  3.     RandomGenerator(){
  4.       seed(time(NULL) * getpid() );
  5.     }
  6.     ~RandomGenerator(){}
  7.   public:
  8.     static RandomGenerator& instance(){
  9.       return m_instance;
  10.     }
  11.     boost::mt19937::result_type operator()(){
  12.       boost::mt19937::result_type r;
  13.       #pragma omp critical
  14.       {
  15. r = boost::mt19937::operator()();
  16.       }
  17.       return r;
  18.     }
  19.   };


 
Je suis ouvert à toute critique (acerbe ou non) sur la propreté de cette solution car l'operateur boost::mt19937::operator()() n'est pas "virtual". Il aurait peut-être été plus propre de le wrapper complètement plutôt que d'en hériter.


Message édité par Lan Wezel le 28-10-2010 à 18:15:34
Reply

Marsh Posté le 29-10-2010 à 21:30:44    

Ton problème est le sujet de cette discussion: http://www.wilmott.com/messageview [...] TARTPAGE=1
En page 3, sont mentionnées des impléms particulières comme http://trng.berlios.de/


Message édité par el muchacho le 30-10-2010 à 00:11:11

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Sujets relatifs:

Leave a Replay

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