I/Oをほとんど実行しない浮動小数点を多用するプロセスがいくつかあります。 1つは「xspec」と呼ばれ、数値モデルを計算し、浮動小数点の結果を毎秒マスタープロセスに返します(stdoutを介して)。それは19レベルでいいです。タイトループで数値計算を行う別の単純なプロセス「cpufloattest」があります。それはいいことではありません。
ハイパースレッディングが無効になっている4コアi7システムがあります。私は各タイプのプロセスを4つ開始しました。 Linuxスケジューラー(Linux 3.4.2)がniceedプロセスによって消費されるCPU時間を適切に制限しないのはなぜですか?
CPU:56.2%us、1.0%sy、41.8%ni、0.0%id、0.0%wa、0.9%hi、0.1%si、0.0%st Mem:合計12297620k 、12147472k使用、150148k空き、831564kバッファ スワップ:合計2104508k、71172k使用、2033336k空き、4753956kキャッシュ PIDユーザーPRNI VIRT RES SHR S%CPU%MEM TIME +コマンド 32399 jss 20 0 44728 32m 772 R 62.7 0.3 4:17.93 cpufloattest 32400 jss 20 0 44728 32m 744 R 53.1 0.3 4:14.17 cpufloattest 32402 jss 20 0 44728 32m 744 R 51.1 0.3 4:14.09 cpufloattest 32398 jss 20 0 44728 32m 744 R 48.8 0.3 4:15.44 cpufloattest 3989 jss 39 19 1725m 690m 7744 R 44.1 5.8 1459:59 xspec 3981 jss 39 19 1725m 689m 774 4 R 42.1 5.7 1459:34 xspec 3985 jss 39 19 1725m 689m 7744 R 42.1 5.7 1460:51 xspec 3993 jss 39 19 1725m 691m 7744 R 38.8 5.8 1458:24 xspec
スケジューラーは、cpufloattestプロセスを8つ開始すると、期待どおりに動作します。そのうちの4つは正常です(つまり、4つはCPUの大部分で、4つはごくわずかです)。
この問題の原因を発見しました。これは、CFSスケジューラの「自動グループ化」機能によるものです。私が行った場合
echo 0> /proc/sys/kernel/sched_autogroup_enabled
その後、すべてが期待どおりに動作します。 Nice 0プロセスが実行されている場合、Nice19プロセスはCPU使用率がほぼゼロに低下します。
自動グループ化が私のユースケースを破るために何をしているのかを正確に見つけて、この答えを更新しようと思います。
編集... IRCで、ワークロードで機能しない場合は無効にする必要があり、Linusが気に入ったクレイジーなパッチだと言ったカーネルの人々とチャットしました。自動グループ化が私のワークロードを好まない理由はわかりませんが、この答えは、同様の問題に遭遇した人々のためにここにあります。
受け入れられた回答にさらに詳細を追加するには...表示されている動作は、Linux 2.6.38(2010年)で追加された自動グループ機能によるものです。おそらく説明されているシナリオでは、2つのコマンドは異なるターミナルウィンドウで実行されました。 sameターミナルウィンドウで実行された場合は、Nice値が効果を発揮することを確認する必要があります。この回答の残りの部分では、ストーリーを詳しく説明します。
カーネルは、自動グループ化と呼ばれる機能を提供し、多数の並列ビルドプロセス(つまり、make(1) -j
フラグ)を使用してLinuxカーネルをビルドするなど、マルチプロセスでCPUを集中的に使用するワークロードに直面した場合のインタラクティブなデスクトップパフォーマンスを向上させます。
setsid(2)
を介して新しいセッションが作成されると、新しい自動グループが作成されます。これは、たとえば、新しいターミナルウィンドウが開始されたときに発生します。 fork(2)
によって作成された新しいプロセスは、その親の自動グループメンバーシップを継承します。したがって、セッション内のすべてのプロセスは同じ自動グループのメンバーです。
自動グループ化が有効になっている場合(これは多くのディストリビューションのデフォルトです)、自動グループのすべてのメンバーは同じカーネルスケジューラの「タスクグループ」に配置されます。 Linuxカーネルスケジューラは、タスクグループ間でCPUサイクルの分散を均等化するアルゴリズムを採用しています。インタラクティブなデスクトップパフォーマンスに対するこれの利点は、次の例で説明できます。
同じCPUをめぐって競合する2つの自動グループがあるとします(つまり、単一のCPUシステム、またはtaskset(1)
を使用してすべてのプロセスをSMPシステム上の同じCPUに限定するとします)。最初のグループには、_make -j10
_で開始されたカーネルビルドからの10個のCPUバウンドプロセスが含まれています。もう1つには、CPUにバインドされた単一のプロセス(ビデオプレーヤー)が含まれています。自動グループ化の効果は、2つのグループがそれぞれCPUサイクルの半分を受け取ることです。つまり、ビデオプレーヤーはCPUサイクルの9%ではなく50%を受け取ります。これにより、ビデオの再生が低下する可能性があります。 SMPシステムの状況はより複雑ですが、一般的な効果は同じです。スケジューラーはCPUサイクルをタスクグループに分散し、多数のCPUバウンドプロセスを含む自動グループがCPUサイクルを犠牲にして占有することはありません。システム上の他のジョブの。
ニース値とグループスケジューリング
非リアルタイムプロセス(デフォルトの_SCHED_OTHER
_ポリシーでスケジュールされたプロセスなど)をスケジュールする場合、スケジューラーは「グループスケジューリング」と呼ばれる手法を採用し、スレッドは「タスクグループ」でスケジュールされます。タスクグループはさまざまな状況で形成され、ここでの関連するケースは自動グループ化です。
自動グループ化が有効になっている場合、自動グループ(つまり、setsid(2)
によって作成された同じセッション)に(暗黙的に)配置されるすべてのスレッドがタスクグループを形成します。したがって、新しい自動グループはそれぞれ個別のタスクグループになります。
グループスケジューリングでは、スレッドのNice値は、スケジューリングの決定に影響します同じタスクグループ内の他のスレッドに対してのみ。これは、UNIXシステムでのNice値の従来のセマンティクスに関していくつかの驚くべき結果をもたらします。特に、自動グループ化が有効になっている場合、プロセスでNice(1)
を使用すると、同じセッション(通常は同じターミナルウィンドウ)で実行される他のプロセスとの相対的なスケジューリングにのみ効果があります。
逆に、(たとえば)異なるセッションで唯一のCPUバウンドプロセスである2つのプロセス(たとえば、それぞれのジョブが異なる自動グループに関連付けられている異なるターミナルウィンドウ)の場合、セッションの1つでプロセスのNice値を変更します他のセッションのプロセスに関連するスケジューラーの決定に関しては効果がありません。これはおそらくあなたが見たシナリオですが、2つのターミナルウィンドウの使用については明示的に言及していません。
ここで説明するように、自動グループ化が従来のNice
の動作に干渉するのを防ぎたい場合は、受け入れられた回答に記載されているように、機能を無効にすることができます
_echo 0 > /proc/sys/kernel/sched_autogroup_enabled
_
ただし、これには、自動グループ機能が提供することを目的としたデスクトップの対話性の利点を無効にする効果もあることに注意してください(上記を参照)。
自動グループのNice値
プロセスの自動グループメンバーシップは、ファイル_/proc/[pid]/autogroup
_を介して表示できます。
_$ cat /proc/1/autogroup
/autogroup-1 Nice 0
_
このファイルを使用して、自動グループに割り当てられたCPU帯域幅を変更することもできます。これは、「Nice」範囲の数値をファイルに書き込んで、自動グループのNice値を設定することによって行われます。許可される範囲は、+ 19(優先度が低い)から-20(優先度が高い)です。
自動グループのNice設定は、プロセスのNice値と同じ意味ですが、他の自動グループの相対的なNice値に基づいて、自動グループ全体へのCPUサイクルの分散に適用されます。自動グループ内のプロセスの場合、受け取るCPUサイクルは、自動グループのNice値(他の自動グループと比較)とプロセスのNice値(同じ自動グループ内の他のプロセスと比較)の積になります。
正確に探しているものではないかもしれませんが、コマンドcpulimit
を試しましたか? Debian/Ubuntuリポジトリではほとんど利用できません。
cpulimit
を使用すると、プロセス全体のCPU時間の何パーセントを占めることができるかを調整できます。 cgroups
を使用することもできますが、cpulimit
の方が簡単で使いやすいです。
優先順位を高く設定するつもりですか?その場合、 負の値 。を使用する必要があります。
出力では、cpufloattestの優先度がxspecよりも高くなっています。
編集:タスクセットを使用して、特定のプロセッサを使用するようにプロセスを設定できますが、この場合は必要ありません。
Xspecを単一のプロセスに減らすだけで、4:1または3:1になります。これは問題なく実行されます。