4

ハードウェアの選択とソフトウェア開発への影響に関して、アプリケーションレベル(PThreads)の質問があります。

マルチコアシングルCPUボックスで十分にテストされたマルチスレッドコードを使用しています。

次のマシン用に何を購入するかを決めようとしています。

  • 6コアのシングルCPUボックス
  • 4コアデュアルCPUボックス

私の質問は、デュアルCPUボックスを使用する場合、コードの移植に深刻な影響を与えるでしょうか?または、より多くのスレッドを割り当てて、OSに残りを処理させることはできますか?

言い換えると、マルチプロセッサプログラミングは、PThreadsアプリケーションのコンテキストでの(シングルCPU)マルチスレッドと何か違いがありますか?

このレベルでは違いはないと思いましたが、新しいボックスを構成するときに、CPUごとに個別のメモリを購入する必要があることに気付きました。その時、私は認知的不協和にぶつかりました。

コードに関する詳細(興味のある人向け): ディスクから大量のデータをメモリの巨大なチャンクに読み取り(もうすぐ24GBまで)、スレッドを生成します。そのメモリの最初のチャンクは「読み取り専用」(私自身のコードポリシーによって強制される)なので、そのチャンクのロックは行いません。4コアのデュアルCPUボックスを見ていると、混乱しました。別々のメモリが必要なようです。私のコードのコンテキストでは、余分なスレッドの束を割り当てた場合、「内部」で何が起こるかわかりません。OSはメモリのチャンクを1つのCPUのメモリバンクから別のCPUにコピーしますか? これは、購入する必要のあるメモリの量に影響します(この構成のコストが上昇します)。 理想的な状況(コスト面およびプログラミングのしやすさ)は、デュアルCPUに1つの大きなメモリバンクを共有させることですが、私が正しく理解していれば、これは新しいIntelデュアルコアMOBO( HP ProLiant ML350e)?

4

3 に答える 3

8

最新のCPU1RAMをローカルで処理し、別のチャネル2を使用してそれらの間で通信します。これは、10年以上前にスーパーコンピューター用に作成されたNUMAアーキテクチャのコンシューマーレベルバージョンです。

アイデアは、メモリにアクセスするためにすべてのコアによって使用されるため、激しい競合を引き起こす可能性のある共有バス(古いFSB)を回避することです。NUMAセルを追加すると、帯域幅が広くなります。欠点は、CPUの観点からメモリが不均一になることです。一部のRAMは他のRAMよりも高速です。

もちろん、最新のOSスケジューラーはNUMAに対応しているため、あるセルから別のセルへのタスクの移行を削減しようとします。同じソケット内で1つのコアから別のコアに移動しても問題ない場合があります。共有されるリソース(1、2、3レベルのキャッシュ、RAMチャネル、IOなど)と共有されないリソースを指定する階層全体が存在する場合があります。これにより、タスクを移動することでペナルティがあるかどうかが決まります。 。適切なコアを待つことは無意味であり、すべてを別のソケットにシャベルで運ぶ方がよいと判断できる場合があります。

ほとんどの場合、スケジューラーに最もよく知っていることを任せるのが最善です。そうでない場合は、で遊ぶことができますnumactl

特定のプログラムの特定のケースについては、最適なアーキテクチャは、スレッド間のリソース共有のレベルに大きく依存します。各スレッドに独自の遊び場があり、ほとんどがその中で単独で機能する場合、十分に賢いアロケータはローカルRAMを優先し、各スレッドがどのセルにあるかはそれほど重要ではなくなります。

一方、オブジェクトが1つのスレッドによって割り当てられ、別のスレッドによって処理され、3番目のスレッドによって消費される場合。同じセル上にない場合、パフォーマンスが低下します。小さなスレッドグループを作成し、グループ内での大量の共有を制限しようとすると、各グループが問題なく異なるセルに移動できます。

最悪のケースは、すべてのスレッドがデータ共有の大乱交に参加している場合です。すべてのロックとプロセスが適切にデバッグされている場合でも、セルで使用可能なコアよりも多くのコアを使用するように最適化する方法はありません。プロセス全体を1つのセルでコアを使用するように制限し、残りを効果的に無駄にするのが最善の場合もあります。

1現代では、AMD-64ビットチップを意味し、Intelの場合はNehalem以上を意味します。

2 AMDはこのチャネルをHyperTransportと呼び、Intelの名前はQuickPathInterconnectです。

編集:

「読み取り専用メモリの大きな塊」を初期化するとおっしゃいました。そして、それに取り組むためにたくさんのスレッドをスポーンします。各スレッドがそのチャンクの独自の部分で機能する場合は、スレッドを生成した後にスレッドで初期化すると、はるかに優れたものになります。これにより、スレッドが複数のコアに広がることが可能になり、アロケータはそれぞれにローカルRAMを選択するため、はるかに効果的なレイアウトになります。スレッドが生成されたらすぐにスレッドを移行するようにスケジューラーにヒントを与える方法があるかもしれませんが、詳細はわかりません。

編集2:

データがディスクから逐語的に読み取られ、処理されない場合はmmap、大きなチャンクを割り当ててread()ingする代わりに使用する方が有利な場合があります。いくつかの一般的な利点があります。

  1. RAMを事前に割り当てる必要はありません。
  2. 操作はほぼ瞬時に行われ、mmap使い始めることができます。データは必要に応じて遅延して読み取られます。
  3. mmapOSは、アプリケーション、 ed RAM、バッファ、およびキャッシュから選択するときに、あなたよりもはるかに賢くなります。
  4. それはより少ないコードです!
  5. 不要なデータは読み取られず、RAMを使い果たしません。
  6. 特に読み取り専用としてマークすることができます。書き込もうとするバグはコアダンプを引き起こします。
  7. OSは読み取り専用であることを認識しているため、「ダーティ」にすることはできません。RAMが必要な場合は、RAMを破棄し、必要に応じて再読み取りします。

ただし、この場合、次のようにもなります。

  • データは遅延して読み取られるため、スレッドが使用可能なすべてのコアに分散したで、各RAMページが選択されます。これにより、OSはプロセスに近いページを選択できるようになります。

したがって、2つの条件が当てはまる場合:

  • データはディスクとRAMの間で処理されません
  • データの各部分は、(ほとんどの場合)1つのスレッドによって読み取られ、すべてのスレッドに影響を受けることはありません。

そうすれば、を使用するだけmmapで、あらゆるサイズのマシンを利用できるようになります。

データの各部分が複数の単一スレッドによって読み取られる場合、どのスレッドが(ほとんど)同じページを共有するかを識別し、それらを同じNUMAセルに保持するようにスケジューラーにヒントを与えることができます。

于 2012-10-04T19:10:21.977 に答える
2

あなたが見ているx86ボックスの場合、メモリが異なるCPUソケットに物理的に配線されているという事実は、実装の詳細です。論理的には、マシンの合計メモリは1つの大きなプールとして表示されます。両方のCPUで正しく実行するために、アプリケーションコードを変更する必要はありません。

ただし、パフォーマンスは別の問題です。クロスソケットメモリアクセスには速度のペナルティがあるため、変更されていないプログラムが最大限に実行されない場合があります。

残念ながら、コードが6コアの1ノードボックスで実行されるのか、8コアの2ノードボックスで実行されるのかを事前に判断するのは困難です。私たちがあなたのコードを見ることができたとしても、それは最終的には知識に基づいた推測になります。考慮すべきいくつかの事柄:

  • クロスソケットメモリアクセスのペナルティは、キャッシュミスでのみ発生するため、プログラムのキャッシュ動作が良好であれば、NUMAはそれほど害にはなりません。
  • スレッドがすべてプライベートメモリ領域に書き込んでいて、メモリへの書き込み帯域幅によって制限されている場合は、デュアルソケットマシンが役に立ちます。
  • メモリ帯域幅にバインドされているのではなく、コンピューティングにバインドされている場合は、6コアよりも8コアの方が適している可能性があります。
  • パフォーマンスがキャッシュ読み取りミスによって制限されている場合、6コアのシングルソケットボックスの見栄えが良くなります。
  • ロックの競合や共有データへの書き込みが多い場合は、これもシングルソケットボックスにアドバイスする傾向があります。

変数はたくさんあるので、検討している構成に一致する貸し出し機をHPリセラーに依頼するのが最善の方法です。次に、アプリケーションをテストして、パフォーマンスが最も高い場所を確認し、それに応じてハードウェアを注文できます。

于 2012-10-05T04:32:39.947 に答える
1

詳細がなければ、詳細な答えを出すのは難しいです。ただし、うまくいけば、以下が問題の組み立てに役立つでしょう。

スレッドコードが適切である場合(たとえば、共有リソースを適切にロックしている場合)、ハードウェアアーキテクチャの変更によって発生するバグは発生しません。不適切なスレッデッドコードは、特定のプラットフォームがCPUキャッシュアクセス/共有などを処理する方法の詳細によってマスクされる場合があります。

シングルチップ、マルチコア、マルチチップの代替案では、メモリとキャッシュの管理に対するアプローチが異なるため、同等のコアあたりのアプリケーションパフォーマンスが変化する可能性があります。

具体的には、CPUごとに個別のメモリを備えたハードウェアを検討している場合、各スレッドはそれが起動するCPUにロックされると想定します(そうでない場合、システムはスレッドのメモリを専用のメモリに移動するためにかなりのオーバーヘッドが発生する必要があります別のコアに)。特定の状況によっては、システム全体の効率が低下する可能性があります。ただし、コアごとに個別のメモリがあるということは、異なるCPUが特定のキャッシュラインで互いに競合しないことも意味します(デュアルCPUのそれぞれの4つのコアは、キャッシュラインをめぐって競合する可能性がありますが、6コアの場合よりも競合が少なくなります。同じキャッシュラインをめぐって競合しています)。

このタイプのキャッシュラインの競合は、偽共有と呼ばれます。それがあなたが直面している問題である可能性があるかどうかを理解するために、以下を読むことをお勧めします

http://www.drdobbs.com/parallel/eliminate-false-sharing/217500206?pgno=3

結論として、適切なスレッド開発の慣行に従った場合、アプリケーションの動作は安定している必要があります(スレッドのスケジューリングの詳細に自然に依存するものを除く)が、パフォーマンスは、実行している内容に応じてどちらの方向にも進む可能性があります。

于 2012-10-04T18:46:35.360 に答える