実行中のプロセスのプリファレンスをワークセットに設定できませんでした。

実行中のプロセスのプリファレンスをワークセットに設定できませんでした。

与えられたCPUコアの数にプロセスを制限しようとしています。ワークセットのマニュアルページによるとこの文書、次が動作するはずです。

[fedora@dfarrell-opendaylight-cbench-devel ~]$ taskset -pc 0 <PID>
pid 24395's current affinity list: 0-3
pid 24395's new affinity list: 0

簡単に言えば - 動作しません。プロセスをロード状態にして、topCPU使用率が約350%であることを確認します(作業セットがない場合と同じ)。最大100%でなければなりません。

taskset -c 0 <cmd to start process>プロセスの作成時に好みを正しく設定できます。cpulimit -p <PID> -l 99また使用一部の作品。どちらの場合も、プロセスを同じ負荷に置くとCPU使用率が100%になります。

ここで何の問題がありますか?

答え1

更新:最新バージョンのワークセットには、「指定されたpidのすべてのタスク(スレッド)で動作」する-a/--all-tasksオプションがあり、以下に示す動作を解決する必要があります。

私はいくつかのスレッドを起動し、CPUサイクルを消費するPythonスクリプトを作成しました。アイデアは非常に簡単なので、これに対して設定されたタスクをテストすることです。

#!/usr/bin/env python

import threading

def cycle_burner():
    while True:
        meh = 84908230489 % 323422

for i in range(3):
    thread = threading.Thread(target=cycle_burner)
    print "Starting a thread"
    thread.start()

Pythonスクリプトを実行するだけでCPU使用率の約150%を消費します。

[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread

ワークセットを使用してPythonスクリプトを起動すると、期待どおりに動作します。上を見ると、Pythonプロセスの使用量が100%であることがわかります。

[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread

興味深いことに、Pythonスクリプトを起動してからすぐにワークセットを使用して起動したばかりのプロセスの好みを設定すると、プロセスは100%に制限されます。出力で、LinuxスケジューラがPythonスレッドを作成する前にBashコマンドの実行を完了することに注意してください。したがって、Pythonプロセスが起動し、CPU 0で実行するように設定され、正しいアフィニティを継承するスレッドが作成されます。

[~/cbench]$ ./burn_cycles.py &; taskset -pc 0 `pgrep python`
[1] 8561
pid 8561's current affinity list: 0-3
pid 8561's new affinity list: 0
Starting a thread
[~/cbench]$ Starting a thread
Starting a thread

この結果はまったく同じことを行いますが、Pythonプロセスの好みを設定する前にPythonスレッドを作成できるようにするこのアプローチとは対照的です。これは、上記の「作業セットが何もしない」結果を複製します。

[~/cbench]$ ./burn_cycles.py &
[1] 8996
[~/cbench]$ Starting a thread
Starting a thread
Starting a thread
[~/cbench]$ taskset -pc 0 `pgrep python`
pid 8996's current affinity list: 0-3
pid 8996's new affinity list: 0

ここで何の問題がありますか?

明らかに、親プロセスの嗜好が変更される前に作成されたスレッドは、親プロセスの嗜好を継承しません。誰かがこれを説明する文書へのリンクを編集できる場合は役立ちます。

答え2

スレッドごとに一度タスクセットを呼び出す必要があると思います。つまり、ps -eL代わりに使用しpgrepてパイプで接続する必要があります。taskset -cp 0

ps -eLo cmd,tid | grep python | perl -pe 's/.* (\d+)$/\1/' | xargs -n 1 taskset -cp 0

これは、すべてのスレッドIDのワークセットを呼び出します。

答え3

努力する数字--physcpubind代わりに(または)を使用してください-C。マニュアルページには次のように記載されています。

...コマンドに対してポリシーが作成され、すべての子孫に継承されます。

(最新バージョンにもオプションがtasksetありますが、すでに実行中のプロセスを変更するのではなく、開始されたジョブの子プロセスでも機能するかどうかはわかりません。)-aSets or retrieves the CPU affinity of all the tasks (threads) for a given PID.taskset

答え4

tasksetオプションを正常に使用しました-a。私はtopプログラムのCPUを大量に消費するvideoconverterdというサーバーを持っています。

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 8991 root      20   0 1299472 346724  47380 S 385.7  4.3  42:41.37 videoconverterd

実行後、taskset -apc 0 8991CPUの負荷が次に低下しました。

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 8991 root      20   0 1221832 293344  47380 S  99.7  3.7  49:13.28 videoconverterd

私はCentOS 7tasksetバージョン2.23.2を実行しています。

関連情報