最新の OS スケジューラでは、プロセスを特定の CPU/コアに手動でロックすることに依然として意味がありますか?

StackOverflow https://stackoverflow.com/questions/1602980

質問

最近、人々が特定のプロセスやスレッドを特定のプロセッサやコアにロックすることがあることを知りました。この手動チューニングが負荷を最適に分散すると考えられています。これは私にとって少し直感に反します。負荷を分散する方法については、人間よりも OS スケジューラの方が適切な決定を下せると思います。古いオペレーティング システムでは、特定のコア ペア間でレイテンシが長くなる、またはあるコア ペア間で共有キャッシュが発生するが別のコア ペア間ではキャッシュが共有されないなどの問題を認識していなかった可能性があります。しかし、Linux、Solaris 10、OS X、Vista などの「最新の」OS には、この情報を認識するスケジューラが必要だと思います。彼らの能力について私が誤解しているのでしょうか?それはOSが実際に解決できる問題であると私は誤解していますか?私が特に興味があるのは、Solaris と Linux に関する答えです。

結果は、私の (マルチスレッド) ソフトウェアのユーザーに、ボックス上でバランスをとることをどのように検討するかを通知する必要があるかどうかです。

役に立ちましたか?

解決

まず、「ロック」はそれを説明する正しい用語ではありません。 「アフィニティ」がより適切な用語です。

ほとんどの場合、気にする必要はありません。ただし、場合によっては、 CPU /プロセス/スレッドアフィニティを手動で設定すると有益な場合があります

オペレーティングシステムは、通常、最新のマルチコアアーキテクチャの詳細を無視しています。たとえば、2ソケットのクアッドコアプロセッサがあり、プロセッサが SMT (= HyperThreadingをサポートしているとします)。この場合、2つのプロセッサ、8つのコア、および16のハードウェアスレッドがあります。そのため、OSは16個の論理プロセッサを認識します。 OSがそのような階層を認識しない場合、パフォーマンスの向上が失われる可能性が高くなります。理由は次のとおりです。

  1. キャッシュ:この例では、2つの異なるプロセッサ(2つの異なるソケットにインストール)がオンチップキャッシュを共有していません。アプリケーションに4つのビジー実行スレッドがあり、多くのデータがスレッドによって共有されているとします。 OSがプロセッサ間でスレッドをスケジュールすると、キャッシュの局所性が失われ、パフォーマンスが低下する可能性があります。ただし、スレッドは多くのデータを共有しておらず(異なるワーキングセットを使用)、有効なキャッシュ容量を増やすことにより、異なる物理プロセッサに分離する方が適切です。また、より注意を要するシナリオが発生する可能性があり、これはOSが認識するのが非常に困難です。

  2. リソースの競合:SMT(= HyperThreading)のケースを考えてみましょう。 SMTは、キャッシュ、TLB、実行ユニットなど、CPUの多くの重要なリソースを共有します。忙しいスレッドが2つしかないとします。ただし、OSは、これら2つのスレッドを同じ物理コアの2つの論理プロセッサーで愚かにスケジュールする場合があります。そのような場合、2つの論理スレッドによってかなりのリソースが競合します。

1つの良い例はWindows 7です。Windows7は、SMT(関連記事)。 Windows 7は、実際には上記の2.ケースを防ぎます。 Core i7(HyperThreading = 8論理プロセッサのクアッドコア)で20%の負荷がかかっているWindows 7のタスクマネージャーのスナップショットは次のとおりです。

 alt text
(ソース: egloos.com

CPU使用率の履歴は非常に興味深いですね。 :) ペアの単一CPUのみが使用されていることがわかります。これは、Windows 7が同じコア上の2つのスレッドを可能な限り同時にスケジュールすることを回避することを意味します。このポリシーは、リソースの競合など、SMTの悪影響を確実に減らします。

多くのキャッシュ、共有最終レベルキャッシュ、SMT、さらにはNUMAを含む最新のマルチコアアーキテクチャを理解するのに、OSはあまり賢くないと言いたいです。そのため、CPU /プロセス/スレッドアフィニティを手動で設定する必要がある場合には、十分な理由があります。

しかし、これが本当に必要だとは言いません。ワークロードパターンとシステムアーキテクチャを完全に理解してから試してください。そして、試行が効果的かどうか結果を確認します。

他のヒント

汎用アプリケーションの場合、CPUアフィニティを設定する理由はありません。 OSスケジューラがプロセスまたはスレッドを実行するCPUを選択できるようにする必要があります。ただし、CPUアフィニティを設定する必要がある場合があります。たとえば、スレッドを1つのコアから別のコアに移行するコスト(CPUアフィニティが設定されていない場合はいつでも発生する可能性があります)が予測不可能な遅延をもたらし、タスクが期限を逃す可能性があるリアルタイムシステムリアルタイム保証を除外します。

この記事をご覧ください。 リアルタイムCORBAのマルチコア対応の実装についてとりわけ、CPUの移行が期限を逃さないようにCPUアフィニティを設定する必要がありました。

論文は次のとおりです。マルチプロセッサ向けリアルタイムパフォーマンスとミドルウェアおよびマルチコアLinuxプラットフォーム

並列処理と複数のコアを念頭に置いて設計されたアプリケーションの場合、OSのデフォルトのスレッドアフィニティでは不十分な場合があります。並列化には多くのアプローチがありますが、これまでのところ、すべてがプログラマーと(少なくともある程度は)ソリューションのマッピング先のアーキテクチャの知識を必要とします。これには、関連するマシン、CPU、スレッドが含まれます。

これは活発に研究されている主題であり、MITのOpenCourseWareにはこれらの問題を掘り下げた優れたコースがあります: http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-189January--IAP --2007 / CourseHome /

多くの人がここで考えていないのは、2つのプロセスを同じプロセッサ(ソケット)で実行することを禁止するという考えです。システムがさまざまな頻繁に使用されるプロセスをさまざまなプロセッサにバインドするのを支援する価値があるかもしれません。これにより、スケジューラがそれ自体を把握するのに十分でない場合、競合を回避できます。

しかし、これはプログラマ向けのタスクではなく、システム管理タスクです。いくつかの高性能データベースサーバーでこのような最適化を見てきました。

最新のオペレーティング システムのほとんどは、コア間で作業を効果的に割り当てます。また、前述したキャッシュの利点を得るために、同じコア上でスレッドを実行し続けようとします。

一般に、よほどの理由がない限り、スレッド アフィニティを設定しないでください。システム上のスレッドが行っている他の作業については、OS ほど洞察力がありません。カーネルは、新しいプロセッサ テクノロジ (ソケットあたり単一の CPU、ソケットあたり複数のコアへのハイパー スレッディング) に基づいて常に更新されています。ハード アフィニティを設定しようとする試みは、将来のプラットフォームでは裏目に出る可能性があります。

MSDN Magazineのこの記事 同時実行性を使用したスケーラビリティ では、Win32でのマルチスレッドの概要を説明しています。 CPUアフィニティについては、

  

Windowsは自動的に採用します   いわゆる理想的なプロセッサー親和性   キャッシュを最大化する試み   効率。たとえば、スレッド   コンテキストを取得するCPU 1で実行   スイッチアウトは再度実行することを好みます   CPU 1で、その一部が   データは引き続きキャッシュに存在します。しかし   CPU 1がビジーでCPU 2がビジーでない場合、   スレッドはCPU 2でスケジュールできます   代わりに、すべてのネガティブキャッシュを使用して   暗示する効果。

この記事では、CPUアフィニティは問題を深く理解せずに操作しないでくださいと警告しています。この情報に基づいて、非常に具体的で十分に理解されているシナリオを除き、あなたの質問に対する私の答えはいいえになります。

Linuxで特定のCPUにプロセスを固定できるかどうかさえわかりません。したがって、私の答えは「NO」です。 -OSに処理させてください。ほとんどの場合、より賢くなります。

編集: win32では、このプロセスを実行するCPUファミリをある程度制御できるようです。今、私は誰かがlinux / posixでも間違っていることを証明するのを待つだけです...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top