38

sched_setaffinityスレッドをCPUに固定するために使用して、パフォーマンスを向上させることができます(状況によっては)

linuxのmanページから:

プロセスを単一のCPUで実行するように制限すると、プロセスが1つのCPUでの実行を停止し、別のCPUでの実行を再開したときに発生するキャッシュの無効化によって引き起こされるパフォーマンスコストも回避されます。

さらに、よりリアルタイムの応答が必要な場合は、そのスレッドのスケジューラポリシーをに変更SCHED_FIFOし、優先度を高い値(最大sched_get_priority_max)に上げることができます。つまり、問題のスレッドは、実行中の他のスレッドを常にプリエンプトする必要があります。準備ができたらCPUで。

ただし、この時点で、リアルタイムスレッドがプリエンプトしたばかりのCPUで実行されているスレッドは、リアルタイムスレッドのレベル1キャッシュエントリの多くを削除している可能性があります。

私の質問は次のとおりです。

  1. スケジューラーが特定のCPUにスレッドをスケジュールしないようにすることは可能ですか?(例:CPUをスケジューラーから完全に非表示にするか、他の方法で)
  2. そのCPUで絶対に実行できなければならないスレッドはありますか?(例:カーネルスレッド/割り込みスレッド)
  3. そのCPUでカーネルスレッドを実行する必要がある場合、カーネルスレッドを使い果たしないように、使用するための妥当な最大優先度の値はどれくらいですか?
4

4 に答える 4

54

答えはcpusetsを使用することです。python cpuset ユーティリティを使用すると、それらを簡単に構成できます。

基本概念

3CPU

  • root: すべての構成に存在し、すべての CPU を含みます (非シールド)
  • system: システム タスクに使用される cpu が含まれます - 実行する必要があるが「重要」ではないもの ( unshielded )
  • user: 「重要な」タスクに使用される cpu が含まれています - 「リアルタイム」モードで実行したいもの (シールド)

このshieldコマンドは、これら 3 つの cpuset を管理します。

セットアップ中はすべての可動タスクをシールドされていない cpuset ( system) に移動し、ティアダウン中はすべての可動タスクをrootcpuset に移動します。セットアップ後、このサブコマンドを使用すると、タスクをシールド( user) cpuset に移動できます。さらに、特別なタスク (カーネル スレッド) をcpusetrootからsystem(したがってusercpuset から) 移動することもできます。

コマンド:

まず、シールドを作成します。当然、シールドのレイアウトはマシン/タスクに依存します。たとえば、4 コアの非 NUMA マシンがあるとします。3 つのコアをシールド専用にし、重要でないタスク用に 1 つのコアを残したいとします。非 NUMA であるため、メモリ ノード パラメータを指定する必要はなく、カーネル スレッドをrootcpuset で実行したままにします (つまり、すべての cpu で)。

$ cset shield --cpu 1-3

一部のカーネル スレッド (特定の cpu にバインドされていないもの) はsystemcpuset に移動できます。(一般に、特定の CPU にバインドされているカーネル スレッドを移動することはお勧めできません)

$ cset shield --kthread on

次に、シールド ( user) またはシールドなし ( system) の cpusets で実行されているものをリストします: (-vプロセス名をリストする詳細の場合) ( -v80 文字以上を表示するには 2 番目を追加します)

$ cset shield --shield -v
$ cset shield --unshield -v -v

盾を止めたいなら(ティアダウン)

$ cset shield --reset

では、シールド内でプロセスを実行してみましょう (以下'--'のコマンドは、 ではなく、実行するコマンドに渡されますcset) 。

$ cset shield --exec mycommand -- -arg1 -arg2

シールドに移動したい実行中のプロセスが既にある場合 (カンマ区切りのリストまたは範囲を渡すことで複数のプロセスを移動できることに注意してください (ギャップがあっても、範囲内のプロセスはすべて移動されます))

$ cset shield --shield --pid 1234
$ cset shield --shield --pid 1234,1236
$ cset shield --shield --pid 1234,1237,1238-1240

高度な概念

cset set/proc- これらにより、CPUsets をより細かく制御できます

設定

cpuset の作成、調整、名前変更、移動、および破棄

コマンド

cpus 1 ~ 3 を使用して cpuset を作成し、NUMA ノード 1 を使用して「my_cpuset1」と呼びます。

$ cset set --cpu=1-3 --mem=1 --set=my_cpuset1

「my_cpuset1」を変更して、CPU 1 と 3 のみを使用するようにします。

$ cset set --cpu=1,3 --mem=1 --set=my_cpuset1

cpuset を破壊する

$ cset set --destroy --set=my_cpuset1

既存の cpuset の名前を変更する

$ cset set --set=my_cpuset1 --newname=your_cpuset1

階層型 CPU セットを作成する

$ cset set --cpu=3 --mem=1 --set=my_cpuset1/my_subset1

既存の cpuset を一覧表示する (レベル 1 の深さ)

$ cset set --list

既存の cpuset とその子を一覧表示する

$ cset set --list --set=my_cpuset1

既存のすべての cpuset を一覧表示する

$ cset set --list --recurse

プロシージャ

スレッドとプロセスを管理する

コマンド

cpuset で実行中のタスクを一覧表示する

$ cset proc --list --set=my_cpuset1 --verbose

cpuset でタスクを実行する

$ cset proc --set=my_cpuset1 --exec myApp -- --arg1 --arg2

タスクの移動

$ cset proc --toset=my_cpuset1 --move --pid 1234
$ cset proc --toset=my_cpuset1 --move --pid 1234,1236
$ cset proc --toset=my_cpuset1 --move --pid 1238-1340

タスクとそのすべての兄弟の移動

$ cset proc --move --toset=my_cpuset1 --pid 1234 --threads

すべてのタスクを 1 つの cpuset から別の cpuset に移動する

$ cset proc --move --fromset=my_cpuset1 --toset=system

固定されていないカーネル スレッドを cpuset に移動する

$ cset proc --kthread --fromset=root --toset=system

カーネル スレッド (特定の CPU に固定されているものを含む) を cpuset に強制的に移動します (注: これはシステムに悲惨な結果をもたらす可能性があります。何をしているのかを確認してください)。

$ cset proc --kthread --fromset=root --toset=system --force

階層の例

階層型 cpuset を使用して、優先グループを作成できます

  1. system1 cpu (0) で cpuset を作成する
  2. 1 cpu で cpuset を作成するprio_low(1)
  3. prio_met2 つのcpu (1-2) を持つ cpuset を作成します。
  4. prio_high3 cpu (1-3) で cpuset を作成します。
  5. prio_all4 つすべての cpu (0-3) を持つ cpuset を作成します(これは root と同じであることに注意してください。root から分離しておくことをお勧めします)。

上記を実現するには、prio_all を作成し、prio_all の下にサブセット prio_high を作成します。

$ cset set --cpu=0 --set=system
$ cset set --cpu=0-3 --set=prio_all
$ cset set --cpu=1-3 --set=/prio_all/prio_high
$ cset set --cpu=1-2 --set=/prio_all/prio_high/prio_med
$ cset set --cpu=1 --set=/prio_all/prio_high/prio_med/prio_low
于 2012-10-25T20:39:23.850 に答える