Réentrance de boost RNG
-
05-10-2019 - |
Question
I ai une boucle qui devrait être parallélisé bien par insering une openmp pragma:
boost::normal_distribution<double> ddist(0, pow(retention, i - 1));
boost::variate_generator<gen &, BOOST_TYPEOF(ddist)> dgen(rng, ddist);
// Diamond
const std::uint_fast32_t dno = 1 << i - 1;
// #pragma omp parallel for
for (std::uint_fast32_t x = 0; x < dno; x++)
for (std::uint_fast32_t y = 0; y < dno; y++)
{
const std::uint_fast32_t diff = size/dno;
const std::uint_fast32_t x1 = x*diff, x2 = (x + 1)*diff;
const std::uint_fast32_t y1 = y*diff, y2 = (y + 1)*diff;
double avg =
(arr[x1][y1] + arr[x1][y2] + arr[x2][y1] + arr[x2][y2])/4;
arr[(x1 + x2)/2][(y1 + y2)/2] = avg + dgen();
}
(sauf si je fais une erreur chaque exécution ne dépend pas du tout autres. Désolé que tous le code est inséré).
Mais ma question est - sont thread-safe RNG boost? Ils semblent se référer au code de gcc pour gcc même si le code gcc est thread-safe, il peut ne pas être le cas pour d'autres plates-formes.
La solution
Naviguer dans les archives de la liste de diffusion Boost donne:
Boost.Random ne maintient pas mondiale Etat qui aurait besoin de protection multi-threading.
Boost.Random est thread-safe aussi longtemps que vous n'accédez pas un objet donné de deux fils simultanément. (Accès deux objets différents est ok, tant car ils ne partagent pas un moteur). Si vous exiger ce genre de sécurité, il est trivial de rouler que vous-même avec une enveloppe de mutex appropriée.
Autres conseils
Si vous êtes inquiet au sujet de la sécurité des threads ne pas utiliser boost, l'utilisation TRNG. Sa bibliothèque de génération de nombres aléatoires parallèle construit pour être exécuté sur le cluster TINA en Allemagne. Il vous permet de créer de multiples flux de nombres aléatoires. Il y a un tutoriel sur la façon d'utiliser TRNG avec OpenMP ici http: // www.lindonslog.com/programming/parallel-random-number-generation-trng/ comme vous essayez de faire. Vous créez un nombre indépendant de flux selon le nombre de threads que vous utilisez, puis tirer d'eux en utilisant le rang du fil. Tout est dans le tutoriel ci-dessus.