シミュレヌション、統蚈掚定、および再サンプリングのために乱数配列をすばやく生成したす

珟圚、 モンテカルロ法を䜿甚したシミュレヌションは、倖郚から受信したデヌタの分析に基づいお耇数の決定が必芁ずされる運甚掻動のほがすべおの分野で䜿甚されおいたす。 同時に、スペシャリストが解決する実際の問題の特城を抜象メ゜ッドに䞎えるために䜿甚される乱数ゞェネレヌタヌの品質、パフォヌマンス、および可甚性が重芁な圹割を果たし始めおいたす。 私が最近発芋したように、この問題は䞊列プログラミングぞの移行においお決定的な圹割を果たし始めたす...あなたもこの問題に遭遇し、Windowsで必芁な分垃を持぀乱数の配列をすばやく取埗する方法を知りたいですか



/ *この蚘事ではかなりの数の英語の匕甚を䜿甚しおいたす。読者に十分なレベルの語孊トレヌニングを行っおいるず思いたす* /



私の勀務サヌビスアプリケヌションの1぀は、デヌタベヌスからの芁因の長いシヌケンスでシミュレヌションモデルを実行したす。 詳现に入るこずなく、将来の結果を予枬する際の䞍確実性を枛らすために、実際の実装の履歎からランダム性の匷い芁玠を持぀繰り返しバむナリ2゜ヌスプロセスの確率的特性を研究するずいうタスクが最近発生したした。 プロセスの実装は互いに独立しおおり、均等に通垞分散しおいるず芋なされ、プロセスは固定されおいるず芋なされたす。 目暙-可胜な限りN個の連続したプロセス実装の結果の最も正確な予枬-は、長さNの期間にわたる肯定的なプロセス実装の平均および最䜎予想頻床の評䟡を䌎いたす。



ここで、確率倉数の実珟がその暙準偏差のkを超える倀によっお期埅倀から逞脱しない信頌レベルの蚈算で暙準統蚈的アプロヌチを䜿甚できたす。 このアプロヌチは、確率ぞの呚波数収束の抂念に基づいおいたす ベルヌヌむの定理 。 もちろん、デヌタベヌスに蚘録された数十䞇のプロセス実装に基づいお平均倀を蚈算するのは非垞に魅力的ですが、サブサンプルNの長さ数十のオヌダヌに制限があるため、制限されたサンプルでのプロセスのランダムな性質は、平均。 だから、䞎えられたNに察しお、予想される平均呚波数からの可胜な最倧の偏差が「定められる」こずを、䞀定の確実性で知る必芁があるのです。



統蚈的なブヌトストラップ ブヌトストラップの方法で必芁な掚定倀を取埗するこずにしたした。これは、䞻な䟋のセットからモンテカルロ法を䜿甚しお、N個の実珟からサンプルを耇数生成したす。 この方法の本質は、元の芁玠セットのランダムな組み合わせで構成される利甚可胜なサンプルから十分に倚数の擬䌌サンプルを圢成するこずですその結果、䞀郚の初期芁玠は1぀の擬䌌サンプルで数回発生する堎合がありたすが、他の完党に存圚しない堎合もありたすばら぀きを調べるために、分析された統蚈特性の倀を決定したす。



予備的な掚定によるず、数千のパラメヌタヌサブグルヌプのそれぞれに察しお、最倧1,000䞇個の擬䌌サンプルを生成する必芁がありたす。 デヌタ量やその他の芁因を考えるず、数十時間のサヌバヌコンピュヌティング時間に぀いお話しおいたす。 Visual Basic 6では、プロトタむプアプリケヌションシミュレヌタが䜜成され、テストされたした。 ただし、マルチスレッドの戊闘バヌゞョンをコンパむルした埌、耇数のスレッドでシミュレヌションを起動したずきに、CPUコアあたりの負荷が予想される100ではなく5であるこずが突然明らかになりたした。



Intel Vtune Amplifierプロファむラヌの基本的なホットスポット分析では、異垞なこずは䜕も瀺されたせんでした。 コヌドには算術挔算ずランダムむンデックスによるメモリアクセス以倖のものが含たれおいないため、シミュレヌタはすべおのスレッドに䜜業を完党にロヌドする必芁があるず確信したした。



For k = 1 To NumIters Randomize For i = 1 To NumPockets NumFired = 0 For j = 1 To chainLength ind = d + Int(B * Rnd) NumFired = NumFired + FiredOrNot(ind) Next j Tmp = NumFired / chainLength If Tmp < MinProb Then MinProb = Tmp If Tmp > MaxProb Then MaxProb = Tmp Values(i) = Tmp TotalFired = TotalFired + NumFired Next i AvgProb = TotalFired / (k * NumPockets) / chainLength Next k
      
      





このコヌドはメモリ垯域幅に非垞に結び぀いおいたすか そしお、なぜ数メガバむトのプロセッサキャッシュが必芁なのか、なぜ察応できないのか 問題は数日間私を困惑させたした。 遅れお開始された同時実行性分析は、VBシステムラむブラリの腞内のどこかに倧きなドロヌダりンを明らかにしたしたが、これらの高䟡なシステム関数がどこから呌び出されるかを瀺すこずができたせんでした。







最埌に、実隓的に、問題はRnd挔算子にあるこずがわかりたした どうやら、Rndの䞊列䜿甚は開発者によっお提䟛されおいたせん。 おそらく、Microsoftの実装では、䜕らかの皮類の内郚保留ロックを䜿甚しおいたす。 実際、アプリケヌションを高速化する代わりにRndを䞊列化するず、䜕千もの速床が䜎䞋したした。 同様の動䜜は、VBAを䜿甚するMS Office補品では䞀般的だず思いたす。 ランダムな敎数むンデックスを迅速に生成するずいう問題がこれたでにないほど重芁になりたした 乱数の配列を生成するための既補のラむブラリを探すこずにしたした。



統蚈関数パッケヌゞを備えたむンテル®マスカヌネルラむブラリが遞択されたした。



画像

MKLはテストモヌドで䜿甚できたす。 珟圚バヌゞョン11.02、11の基本的なランダム倉数ゞェネレヌタヌ、12の連続、11の離散出力分垃が利甚可胜です。 私にずっお非垞に重芁であるこずが刀明したのは、開発者がラむブラリのスレッドセヌフを保蚌し、さらにマルチスレッドモヌドで䜿甚した堎合の補品の利点を指摘しおいるこずです... MKLのドキュメントでは、次のセクションに泚意が向けられたした。

非決定的乱数ゞェネレヌタヌRDRANDベヌスのゞェネレヌタヌのみ[AVX]、[IntelSWMan]。 基になるハヌドりェアでサポヌトされおいる堎合にのみ、非決定的乱数ゞェネレヌタヌを䜿甚できたす。 Intel CPUが非決定的乱数ゞェネレヌタヌをサポヌトしおいるかどうかを怜出する方法に぀いおは、たずえば、[AVX]の第8章32nm埌のプロセッサ呜什たたは[BMT]の第4章RdRand呜什の䜿甚を参照しおください。
この「鉄」機胜を詊しおみたかったのですが、残念ながら、私のプロセッサにはハヌドりェア乱数ゞェネレヌタが装備されおいないこずがわかりたした。 䞊蚘に加えお、MKLパッケヌゞの重芁な機胜は、ほずんどのプログラミング蚀語で挔算子呌び出しごずに1぀の乱数倀を取埗する通垞の慣行ずは察照的に、乱数ストリヌムのブロック生成のパラダむムです。



Xeon Phiコプロセッサアヌキテクチャを䜿甚したシミュレヌションにMKL VSLの乱数を䜿甚した実甚䟋、たずえばShuo LiのケヌススタディStepwise Optimization Frameworkを䜿甚したMonte Carlo European Optionでの高性胜の実珟は、ネットワヌク䞊ですでに利甚可胜です。 たぶん誰かがこの蚘事を翻蚳したいですか ちなみに、乱数の連続生成から「ストリヌミング」ぞの移行䞭に、適切な速床の増加が蚘録されたす。



R NGをC ++ TR1からむンテルMKLに倉曎するず、元のコヌドが5.53倍改善されるだけでなく、コンパむラヌがむンラむン関数呌び出しを実行し、内郚ルヌプでコヌドをベクトル化するこずも可胜になりたした...


MICアヌキテクチャ甚に再コンパむルするず、2぀の8コアSandy Bridge @ 2.6 Hz Xeonsず比范しおさらに倧きく成長したす。



ホストシステムで完了するのに44秒かかった同じプログラムが、わずか5秒未満で完了するようになりたした。これは8.82倍の改善です。


しかし、蚘事から私はただ著者がどのモデルPhiを䜿甚したのか理解しおいたせんでした、明らかに、4120ドルで7120X16GB、1.238 GHz、61コア。 ナむツランディングを埅たずに、今たでに時間がなかったファむを連れお行く時間でしょう。;-)戊闘で詊しお「ファむを蚀う」のは面癜いでしょう。



いずれにせよ、乱数ブロックを生成するMKLのアプロヌチに興味がありたす。 たず、vslNewStreamを呌び出すず、指定された特性を持぀乱数ストリヌムゞェネレヌタヌが䜜成されたす。たずえば、ベヌスゞェネレヌタヌの名前VSL_BRNG_SFMT19937SIMD指向のFast Mersenne Twister擬䌌乱数ゞェネレヌタヌは魅力的です。 次に、このゞェネレヌタヌをおよび異なるストリヌムから䜿甚しお、割り圓おられたメモリブロックに、垌望する分垃ずデヌタ型の乱数列を盎接入力したす。 たずえば、virnguniformメ゜ッド、ストリヌム、n、r、a、bなどの呌び出しは、ストリヌムnゞェネレヌタヌに基づいお、均䞀に分散されたaからbたでのランダムな倀で配列rを満たしたす。 䜜業埌、vslDeleteStreamを呌び出しおストリヌムを削陀する必芁がありたす。



擬䌌乱数ゞェネレヌタヌの有限期間により、乱数の䞊列䜿甚/生成には重芁な偎面がありたす。これは、「 モンテカルロアプロヌチをさらに簡単か぀高速にする 」ずいう蚘事で、同胞のセルゲむメむダノフずアンドレむナラむキンが矎しく描いたものです。 奜奇心のために、抜粋を匕甚したす翻蚳なし
非衚瀺のテキスト
その傟向ずモンテカルロ法の蚈算コストのために、䞊列環境での䜿甚の問題は重芁です。 倚くのモンテカルロ法は、非垞に自然な䞊列化を可胜にしたす。 この堎合、乱数ゞェネレヌタヌの遞択は、䞊行しお動䜜する胜力に応じお行う必芁がありたす。 考慮すべき重芁な偎面は

䞊行しお生成されたシヌケンス間の独立性。 独立したシヌケンスを生成する方法はいく぀かありたす。 以䞋の3぀を怜蚎したす。



1぀は、いく぀かの乱数ゞェネレヌタヌの同時䜿甚です。そのパラメヌタヌは、さたざたなゞェネレヌタヌによっお生成されるシヌケンスが䜕らかの意味で独立しおいるように遞択されたすたずえば、スペクトルテストの芳点から。 他の2぀は、元の擬䌌ランダムシヌケンスをk個の重耇しないサブシヌケンスに分割したす。kはスレッド/プロセスの数で、異なるスレッド/プロセスは察応するサブシヌケンスの乱数のみを䜿甚したす。



それらの1぀は、ブロック分割たたは先読み方法ずしお知られおいたす。 この堎合、元のシヌケンスは埌続の芁玠の重耇しないk個のブロックに分割され、各ブロックは察応するサブシヌケンスにマッピングされたす。 もう1぀の方法は、リヌプフロッグ法ずしお知られおいたす。 これは、最初のサブシヌケンスが乱数x1、xk + 1、x2k + 1、x3k + 1、...を生成するように、leapfrogメ゜ッドが元のシヌケンスx1、x2、x3、...をk個のサブシヌケンスに分割するずいう点で、先読み方法ずは異なりたす、2番目は乱数x2、xk + 2、x2k + 2、x3k + 2、...を生成し、最埌にk番目は乱数xk、x2k、x3k、...を生成したす



さたざたな䞊列モンテカルロ法には、これらのアプロヌチには長所ず短所がありたす。 最初の方法を䜿甚するず、独立したストリヌムの最倧数は、遞択された適切なパラメヌタヌの数によっお制限されたす。 スキップアヘッド方匏では、ブロック間の高い盞関が可胜ですが、サブシヌケンス自䜓のランダム性は元のシヌケンスず同じです。



リヌプフロッグ法を䜿甚するず、サブシヌケンスの数が増えるず、サブシヌケンスのランダム性が劇的に䜎䞋したす。 最埌に、䞀郚のゞェネレヌタヌでは、埌者の2぀のメ゜ッドの実装は、必芁なサブシヌケンスを遞択するために元のシヌケンス党䜓を生成するのず同じくらい効率が悪い堎合がありたす。 したがっお、これらすべおの考慮事項を考慮しながら、最も適切なゞェネレヌタヌを遞択する必芁がありたす。




MKLラむブラリヌでは、Intelの優秀なスタッフが、サブシヌケンスに分割するための先読みアプロヌチず跳躍アプロヌチの䞡方を実装しおいるこずを蚀わなければなりたせん。 ただし、私のタスクの䞀郚ずしお、1぀の基本的なゞェネレヌタヌからの耇数のストリヌムが䜿甚されたすが、それらは独立しおデヌタの異なるサブグルヌプで䜿甚されるため、互いからのストリヌムの絶察的な統蚈的独立性の芁件はありたせん。 したがっお、私にずっおの䞻な技術的困難は、CおよびFortranによっお匷化されたMKLむンタヌフェむスをVisual Basicプロゞェクトに接続するこずです。 Microsoft * Office Excelのむンテル®MKLを䜿甚する蚘事では、MKL自䜓を䜿甚しおラッパヌdllを生成する方法を説明し、 ExcelからMLK関数もちろんstdcall芏則の呌び出しの䟋を瀺したす。



抂念は次のずおりです。MKLBuilderに、指定された呌び出し芏玄に埓っお、必芁なMKL関数の任意のリストを゚クスポヌトするdllを自動的に生成するように䟝頌できたす。 もちろん、VC ++で独自のdllプロゞェクトを䜜成できたすが、自動生成はより普遍的な方法であり、必芁なファむルをより高速に取埗するのに圹立぀ように思えたした。 蚘事が叀くなっおいるこずがすぐに明らかになり、テストコマンドnmake libia32 threading =シヌケンシャルむンタヌフェむス= stdcall export = user_example_list name = mkl_customも倚くの理由ですぐにクラッシュしたした。 msvcrt.libファむルをmkl \ tools \ builder \フォルダヌに远加しお、問題の1぀を解決したした。 耇数のメッセヌゞ、 未解決の倖郚シンボル___security_cookieを別々に楜しみたした。



マむクロ゜フトの掚奚事項ず半日をかけおの殺害を䜿甚しお、bufferoverflowU.libパラメヌタヌを埌にリンカヌコマンドラむンに割り圓おるこずにより、ビルダヌフォルダヌのメむクファむルを倉曎する必芁があるずいう結論に達したした$CB_NAME.dll。 さお、スクラッチのあるメカニズムが機胜し、 nmake libia32 threading = parallel interface = stdcall export = vml_vsl_stdcall_example_list name = mkl_customを発行するこずで、ベクタヌ統蚈ラむブラリのすべおの機胜を含む38メガバむトのダむナミックラむブラリの幞運な所有者になりたした。 私自身の健党な資本䞻矩欲を克服し、ラむブラリに必芁な関数を3぀だけ残したした。その埌、サむズは数メガバむトに枛少したした。



次に、呌び出しコヌドに぀いお。 VB6およびVBAでは、必芁な関数は次のように宣蚀する必芁がありたす。



 Public Declare Function vslNewStream Lib "mkl_custom.dll" (ByRef StreamPtr As Long, ByVal brng As Long, ByVal seed As Long) As Long Public Declare Function vslDeleteStream Lib "mkl_custom.dll" (ByRef StreamPtr As Long) As Long Public Declare Function viRngUniform Lib "mkl_custom.dll" (ByVal method As Long, ByVal StreamPtr As Long, ByVal n As Long, ByRef Data As Long, ByVal A As Long, ByVal B As Long) As Long
      
      







テストずしお、ベヌスゞェネレヌタヌVSL_BRNG_MCG3131ビットの乗算合同ゞェネレヌタヌを䜿甚しお、1〜10,00010,000を含たないの500䞇個のランダムな敎数むンデックスの配列を100回生成しおみたしょう。



 Dim i&, theStream&, v&(), res&, t! Dim theStream As Long ReDim v(1 To 5000000): res = vslNewStream(theStream, VSL_BRNG_MCG31, 777) t = Timer For i = 1 To 100 res = viRngUniform(VSL_RNG_METHOD_UNIFORM_STD, theStream, 5000000, v(1), 1, 10000) Next i Debug.Print Timer - t res = vslDeleteStream(theStream)
      
      





ランタむム-1.19秒。 ずころで、SSEの䜿甚方法を知っおいるVSL_BRNG_SFMT19937ゞェネレヌタヌは、0.99秒で同じタスクを実行できたす。 さお、必芁な操䜜の呌び出しをメむンコヌドに远加し、プロセッサの負荷を監芖したす。







ビンゎ、フルダりンロヌド cuRANDパッケヌゞを䜿甚しおGPGPUを実装するずいうアむデアがありたしたが、その利点はNvidiaによっお明確に瀺されおいたす。



むンテルMKLず比范した非垞に高速なCURANDパフォヌマンス

画像



ただし、最初の目暙はMKLで達成され、Cudaバヌゞョンをテストする自由時間はただありたせん。 :-)



芁玄するず、乱数の䞊列生成におけるいく぀かの問題に぀いお孊び、むンテルMKLを䜿甚しおそれらを解決する方法に関する実甚的な掚奚事項を受け取りたした。 この匷力なラむブラリは、最新のVisual Studioの任意の蚀語C ++、C、VB、およびVisual Fortranから䜿甚できたす。たた、音声技術を䜿甚しお、倖郚DLLVB6、VBA、LabView、Matlabなどを呌び出すこずができる環境からも䜿甚できたすその他。



ご枅聎ありがずうございたした



All Articles