最新のCPU1はRAMをローカルで処理し、別のチャネル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する代わりに使用する方が有利な場合があります。いくつかの一般的な利点があります。
- RAMを事前に割り当てる必要はありません。
- 操作はほぼ瞬時に行われ、
mmap
使い始めることができます。データは必要に応じて遅延して読み取られます。
mmap
OSは、アプリケーション、 ed RAM、バッファ、およびキャッシュから選択するときに、あなたよりもはるかに賢くなります。
- それはより少ないコードです!
- 不要なデータは読み取られず、RAMを使い果たしません。
- 特に読み取り専用としてマークすることができます。書き込もうとするバグはコアダンプを引き起こします。
- OSは読み取り専用であることを認識しているため、「ダーティ」にすることはできません。RAMが必要な場合は、RAMを破棄し、必要に応じて再読み取りします。
ただし、この場合、次のようにもなります。
- データは遅延して読み取られるため、スレッドが使用可能なすべてのコアに分散した後で、各RAMページが選択されます。これにより、OSはプロセスに近いページを選択できるようになります。
したがって、2つの条件が当てはまる場合:
- データはディスクとRAMの間で処理されません
- データの各部分は、(ほとんどの場合)1つのスレッドによって読み取られ、すべてのスレッドに影響を受けることはありません。
そうすれば、を使用するだけmmap
で、あらゆるサイズのマシンを利用できるようになります。
データの各部分が複数の単一スレッドによって読み取られる場合、どのスレッドが(ほとんど)同じページを共有するかを識別し、それらを同じNUMAセルに保持するようにスケジューラーにヒントを与えることができます。