つまり、OS の実装において、どのメカニズムがこの仕事を行うことができるのでしょうか? たとえば、Linux カーネルでは? または、誰もが知っているように、Windows タスク マネージャーなど、これを便利に実現できるツールがありますが、内部メカニズムは何ですか?
1 に答える
素早い回答
Linuxでは、確認する必要があるのはsched_setaffinity()またはpthread_setaffinity_np()です。
長い答え
コアアフィニティ(つまり、特定のコアにプロセス/スレッドを指定する)には十分注意する必要があります。最近のCPUとOSは、一般的なケースでコアアフィニティをいじる必要がないようにするためにあらゆる種類のことを行っており、いじって間違えると、それらはあなたに対して働き始める可能性があります。
例
デュアルチップi7プラットフォームでは、実際に非常に複雑になる可能性があります。このようなプラットフォームでは、ハイパースレッディングはBIOSが16コアを報告することを意味し、そのうち8コアのみが実際のものです。2つのスレッドをコアとそのハイパースレッドの分身にバインドすると、2つの遅いスレッドが簡単に発生する可能性があります。
また、メモリは通常、2つのチップ間で一度に4kページずつインターリーブされます(別のBIOS設定)。したがって、スレッドを特定のコアにバインドすると、操作対象のデータからさらに離れた場所にスレッドを配置できます。これにより、2つのチップ間のQPIリンクが過負荷になり、すべてが遅くなる可能性があります。ところで、メモリをチップにローカルに割り当てることもできます。これを見てください。それは複雑なトピックですが、あなたもそれを受け入れる必要があるかもしれません。
一般的に言えば、マシンのコア、チップ、およびSIMM全体でのスレッドとそのメモリの最適な展開は、各PCに固有です。たとえば、マシン内の2つのi7について考えてみます。最適な展開は、接続されているメモリSIMMの数によって異なります。これらはオペレーティングシステムが十分に認識していることであり、通常、最高のパフォーマンスを得るためにスレッドを移動するのに非常に効果的です。
自分で配布する方が良いと感じるような、非常に特別な状況が必要です。また、ハードウェア構成が非常に固定されていない限り、実行するたびに最適なデプロイメントを決定するようにアプリケーションを作成する必要があります。それは多くのプログラミング作業です。
概要
要するに、通常は一人でよく放置するのが最善です。
インテルが行ったこと
少し前に戻って、2つ以上のチップが存在するIntelの現在の設計の背後にある哲学を見てみましょう。
Intelは、一般に、コンピューターは、スレッドとプロセス間でデータを適度に共有するだけで、さまざまなデータセットに対して一度に多くのさまざまなタスクを実行することを決定しました。これにより、QPIを使用してSMPアーキテクチャを合成し、CPUを共通のメモリマップにバインドできます(そうでない場合は、SMPではなく厳密にNUMAになります)。一般的な場合、これにより優れたパフォーマンスが得られます。もちろん、AMDは何年も前に同じ結論に達し、Hypertransportを使用して実装していました。
重要なのは、QPIを介して間接的にのみであっても、マシン全体のすべてのコアがメモリ全体を認識できるため、アプリケーションとオペレーティングシステムに関する限り単純化することです。
ルールの例外
ただし、アプリケーションの性質が各コアのスレッドによって処理される大規模なデータセットである場合、QPIを介したメモリのリモート性が問題になる可能性があります。アーキテクチャはすべてのCPU間でキャッシュコヒーレンシを維持する必要があるため、QPIリンクがメモリアクセスとキャッシュコヒーレンシトラフィックで破壊される可能性があります。たとえば、私が使用しているプラットフォームでは、QPIはわずか19GB /秒ですが、各CPUには3つのメモリバンクに対して25GB/秒があります。これは、Intelの最近のチップでは変更されている可能性があります。
このような状況では、2つのチップをNUMAアーキテクチャであるかのように扱う方がよい場合があります。これは、データセットNUMAの2つのコピーを割り当てて、各CPUが独自のコピーを持つようにすることで実行できます。また、スレッドにローカルメモリのみを処理させることもできます。これにより、QPIリンクの負担が軽減されます。
チップの動作を回避する
この程度の最適化に取り組んでいると、現代のCPUアーキテクチャに組み込まれている一般化を急速に嫌うようになります。たとえば、キャッシュは、ロードするデータとそのデータをいつロードするか、RAMやその他のキャッシュをいつ更新するかを想定しています。一般的にはそれで問題ありませんが、よく知っている場合もあります。
私にとって、これまでで最高のCPUは、Playstation 3で使用されているCellプロセッサです。8つの数学コアにはキャッシュがないため、キャッシュの一貫性も何もありません。プログラマーは、DMAエンジン(インテルに含めてほしいもの)にデータを適切な場所に適切なタイミングで移動させて適切なコードで処理させる責任を単独で負っています。または、データをそのままにして、コードをデータにDMAすることもできます。それは非常に複雑で、多くの頭脳の力を必要としますが、それを正しく行うと、驚異的な数学のパフォーマンスを得ることができます(2005年には200GFLOP、Intelよりもはるかに進んでいます)。
どの哲学が正しいですか?さて、IntelはCorethisとXeonthatを打ち負かしていますが、Cellは瀕死/死んでいます。すべてを自分で制御することで最高のパフォーマンスを引き出すことができるプログラマーはそれほど多くないことがわかりました。