私は C++ プログラミングと Stackoverflow の両方の初心者であり、1 コアと i5 CPU の 25% を使用する BlackJack オッズ シミュレーターをより高速に実行する必要があります (理想的には 3 ~ 4 倍)。ループを並列化するさまざまな方法に圧倒されます。これは、このプログラムの最も CPU を集中的に使用する関数の最も外側のループであり、並列化を行わなくても、ゆっくりではありますが正常に動作していました。私は Microsoft Visual Studio 2012 でプログラムを実行しており、並行処理ライブラリによって提供される並列化された for ループを試しましたが、テストしたところ、希望どおりに正確に 4 つのスレッドと 100% の CPU 使用率を取得する代わりに、タスク マネージャーが表示されました。プロセスはさまざまな数のスレッドとさまざまな量の CPU 使用率でシャッフルされ、思ったほど速く実行されませんでした。http://msdn.microsoft.com/en-us/library/hh872235.aspx )、しかし多くの制約がありました (条件ステートメント、関数呼び出し、変数の作成と割り当て、ループの途中でのインクリメンタルなど)。そのため、非常に複雑なループではおそらくうまくいかないだろうと判断しました。Microsoft の #pragma loop(hint_parallel(0)) 自動並列化機能を使用すると非常に高速でしたが、プログラムの開始から各コアに 1 つずつ、正確に 4 つのスレッドが自動的に作成され、一貫して 100% の CPU 使用率が使用されました。理想的だと思うものです-それは私の仕事に合わないと思います。
私のプログラムの各シミュレーションまたはループは、シミュレーションの結果が基づいているすべての変数 (デッキ内のカードの数、2 の数、3 の数など) が同じであるため、残りの部分から完全に独立しています。シミュレーションの実行の開始時と同様に、シミュレーションの実行の終了 (すべての変数とベクトルが完全に元の状態に戻されない場合、assert ステートメントがオフになります)。最も外側のループの反復と次の反復で異なる唯一の変数は、二重の「期待される結果」または「平均」です。私の目的のために、各要素 (10 要素、カードの種類ごとに 1 つずつ) が必要だと思います。 BlackJack では 2 から 11 までの値) を最も外側のループで使用して、独自の「期待される結果」を持たせます。variable または、予想される結果変数が異なるスレッドによって変更されるアトミック double である場合。シミュレーションの最後に、10 個の異なるスレッド ローカルの「期待される結果」変数がある場合、2 からエースまでの値のカードを最初に引くために、その「期待される結果」変数をメインに戻し、他の「期待される結果」変数と組み合わせたいと考えています。 " 最終結果を取得するための変数 - あなたの "家の端".
では、マルチスレッド化するにはどうすればよいでしょうか。あなたが私の立場だったら、どの図書館(図書館)を利用しますか?1 つのスレッドがループの最初の値を取得し、2 番目のスレッドが 2 番目の値を取得し、3 番目のスレッドが 3 番目の値を取得し、4 番目のスレッドが 4 番目の値を取得し、スレッド #1 が for ループで 5 番目の値を取得するようにすることはできますか?ループの最初の反復で終了しますか? 固定数のスレッドまたはスレッド プールを使用する必要がありますか (「スレッド プール」などの概念をまだ完全に理解していません)。別のスレッド ローカル変数 (expected_outcome_1、expected_outcome_2) を作成する必要がありますか、それともロックを使用する必要がありますか? 複雑な関数でも自動並列化を機能させることはできますか?
最後にちょっとしたこと。このプログラムの元のバージョンは再帰的で、ディーラー Draws_Card の機能があり、dealerScore < hard17 (|| soft16) の場合、Draw_Card を再帰します。再帰の良い点は、コードがループの束を使用するよりもコンパクトであることです。また、ネストされたループの途中にあるエラーよりも、スタックの途中にあるエラーを見つけて修正する方が難しいこともわかりました。また、ループが誤って非常に深いまたは無限の再帰に入ることはありません。しかし、人々に私のコードを読んでもらいたい場合、約 15 個のネストされたループではうまくいかない可能性があるため、わかりやすくするために末尾再帰にし、再帰呼び出しをループに最適化することができます。「for」を並列化するのと同じくらい簡単に、末尾再帰関数を並列化 (または自動並列化) するのは簡単ですか? ループ?もしそうなら、ネストされたループをまとめて取り除きたいからです。