Serviceを読んで理解し、同意したものとみなします。スタック・オーバーフローはプログラマーとプログラミングに熱心な人のためのQ&Aサイトです。1,108件11C++/c++11の環境で疑似乱数生成のメルセンヌ・ツイスターを並列化して動作させる方法をご教示下さい。簡単には並列化できないようです。0;}乱数生成器のmt19937をベースにしているのですが、openmpのループの中からこの乱数生成器を呼び出しても、乱数生成器自体は並列化されているわけではないようです。uniform()は個別のスレッドから呼び出されているようですが、乱数生成器の部分は共通して動作しており、並列化はされていないようです。この乱数生成器自体を並列化したいと考えています。票2本質的でないuniform_realとvariate_generatorを取り除いて説明します。}}メルセンヌ・ツイスターに限らず全ての疑似乱数生成器はある状態で得られる乱数は決まっているある状態から遷移する次の状態は決まっている最初の状態を決定する値をseedと呼ぶという特徴があります。private(gen)を指定したとしても、得られる乱数はスレッド間で同じになりますし、遷移する次の状態も同じになります。結果的にスレッドごとに得られる乱数列は同一のものとなってしまいます。これを解消するにはまずはスレッド間排他を行うことです。}}ただし、排他のコストが高すぎるため並列化している意義が薄くなります。そこで排他するよりもスレッド毎に疑似乱数生成器を用意することです。その際、個々の疑似乱数生成器のseedは異なる値に設定する必要があります。}}以上を踏まえて質問のコードは次のように書けます。さんの回答で触れられているページで紹介されている並列対応版MTや、この投稿で触れられている方法を使う必要があるのかもしれません。残念ながら詳しくないのできちんとは書けませんが......。1:35動作確認しました。これで乱数生成が並列化されています。さんが指摘しているようにモンテカルロ法での使用を考えると、さらに改善の余地があります。上のtest1()のような、ある程度の長さの乱数列の生成を、多数回呼び出すような場合があります。そのときに、このtest1()のように呼び出されるたびにseedをrandom_deviveで与え直すと、MTの良い性質が生かせないようになります。test1()の中のNNが小さな値で、test1()の呼び出し回数が多くなれば、得られる乱数列はrandom_deviceによるseedの生成に強く依存していることになります。(悪い影響が出るとしても、それを見極めるのは難しい状況になると思いますが)また乱数列の再現性を確保するために、seedを自分で設定したい場合もあります。さん、質問者さんに応えたのではなく、質問文に答えている点をご理解ください。NNがそこそこ大きくtest1()が1回しか呼ばれない質問に答えました。後だしでコメントされるのではなく、質問文に含めていただけますでしょうか。C++11のthread_localを使う方法もあるようですが、環境によってはOpenMPと共存できるかどうか分かれるようです。0:53@sayuriさん、失礼しました。このtest1()の呼び出しを多数繰り返すという想定で、議論を続けたいと思います。質問文に追加しようと思います。件のコメントを表示0OpenMP並列処理でワーカスレッド毎にオブジェクトを複製したい場合、firstprivate節にて実現できます。このケースでは、それぞれのスレッドにて同一擬似乱数系列が得られることに注意ください。|-1乱数呼び出し部分を排他制御するか、あるいはスレッドセーフなメルセンヌ・ツイスターの実装を利用してはどうでしょうか。mt-liteはスレッドセーフでありマルチスレッドで使えるとあります。いう意味ですから、Boost.Randomと同条件ですね。5:47マルチスレッドで使いたいのではなくて、スレッド毎に独立した乱数生成器を持ちたいという質問だったんですね。Pageが詳しいです。参考になる情報を得られると思います。|回答スタック・オーバーフローに参加してくれて、ありがとうございます!質問の回答を共有してください。回答を説明し、自分の検討結果も共有してください。意見を述べること(意見を述べるなら、参照リソース、自分の経験で意見をサポートしてください)さらにサポートが必要な場合このヘルプを参考してください。“回答を投稿”をクリックすることで利用規約、プライバシーポリシー、及びクッキーポリシーに同意したものとみなされます。タグが付いた他の質問を参照するか、自分で質問をする。質問のフィードこのRSSフィードを購読するには、このURLをコピーしてRSSリーダーに貼り付けてください。