単一のマシンで複数のスレッドを使用して、浮動小数点値の配列の平均値を見つけようとしています。配列のサイズやメモリの制約は気にしません (適度なサイズの配列で、複数のスレッドを保証するのに十分な大きさであると仮定します)。特に、最も効率的なスケジューリング アルゴリズムを探しています。静的ブロックアプローチが最も効率的であるように思えます。
したがって、x 個のマシン コアがあることを考えると、配列を array.size/x 値にチャンクし、各コアにそれぞれの配列チャンクの結果を合計させるのが妥当と思われます。次に、各コアからの合計結果が加算され、最終結果は、この値を配列要素の総数で割ったものになります (注: 配列要素の数が x で正確に割り切れない場合、私は最適化を認識しています)要素をスレッド間でできるだけ均等に分散します)。
配列は明らかにスレッド間で共有されますが、書き込みが含まれていないため、ロック メカニズムを使用したり、同期の問題を心配したりする必要はありません。
私の質問は: これは実際にこの問題に対する最も効率的なアプローチですか?
対照的に、たとえば、静的インターリーブ アプローチを考えてみましょう。この場合、4 つのコア (スレッド) がある場合、スレッド 1 は配列要素 0、4、8、12... で動作し、スレッド 2 は要素 1、5、9、13... で動作します。各コアが継続的にキャッシュ ミスを取得するため、より悪いように見えますが、静的ブロック アプローチは、各コアが成功値に基づいて動作し、データの局所性を利用することを意味します。私が実行したいくつかのテストは、これを裏付けているようです。
では、静的ブロックよりも優れたアプローチを指摘したり、これが最善のアプローチである可能性が最も高いことを確認したりできる人はいますか?
編集:
Java と Linux (Ubuntu) を使用しています。関連する言語/プラットフォームについてはあまり考えずに、ワークロードを複数のスレッドに手動で割り当てることを含むスケジューリングの観点から問題を抽象的に見てください。しかし、言語とプラットフォームが重要な要素であることは理解しています。
Edit-2:
さまざまな配列サイズ (double) を使用したタイミング (ナノ時間/1000) を次に示します。
シーケンシャル タイミングでは、単一の Java スレッドが使用されました。他のものは、並行して動作するすべての利用可能な (4) コアを使用して、それぞれのスケジューリング戦略を実装しました。
1,000,000
要素
:
---
シーケンシャル
5765
1642
1565
1485
1444
1511
1511
1446
1448
1465
1443
---
静的
ブロック
15857
4571
1489
1529
1547
1496
1445
1415
1452
1661
---
静的
インター
レッド
9692
50,000,000 elements:
---Sequential
73757
69280
70255
78510
74520
69001
69593
69586
69399
69665
---Static Block
62827
52705
55393
53843
57408
56276
56083
57366
57081
57787
---Static Interleaved
179592
306106
239443
145630
171871
303050
233730
141827
162240
292421