web-dev-qa-db-ja.com

実行中のプロセスに対して排他的なCPUの可用性を確保するにはどうすればよいですか?

最初は、OSがプロセスの実行を管理する仕事をしているので、質問は少しばかげている/混乱しているようです。

ただし、一部のプロセスがCPU/IOにバインドされている量を測定したいのですが、OSが、たとえば、スケジュールされたOSプロセスなどの実験を妨害しているように感じます。

例として次の状況を考えてみます。プロセスAを2回実行し、ツール「time」から次の出力を取得しました(秒単位の時間列)。

+---+-------+---------+-----------+---------+
|Run|Process|User Time|System Time|Wall time|
+---+-------+---------+-----------+---------+
|1  |A      |196.3    |5.12       |148.86   |
|2  |A      |190.79   |4.93       |475.46   |
+---+-------+---------+-----------+---------+

ご覧のとおり、ユーザー時間とシステム時間は似ていますが、両方の経過時間は大幅に変化します(約5分の差)。私の環境に何かがあるように感じて、何らかの競合を引き起こしました。

私は実験中のあらゆる種類のノイズを回避するためにすべての可能なバックグラウンドプロセス/サービスを停止したいのですが、私は初心者/中級のUNIXユーザーであり、これを保証する方法がわかりません。

Linux 4.4.0-45-genericUbuntu 14.04 LTS 64ビットを使用しています

本当に助かりました。不足している情報が必要な場合は、すぐに投稿を編集します。

CPU情報

$ grep proc /proc/cpuinfo | wc -l
8
$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 60
Stepping:              3
CPU MHz:               4002.609
BogoMIPS:              7183.60
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU(s):     0-7
31

CPUがOSによって使用されないカーネルオプション構成があり、それはisolcpusと呼ばれます。

isolcpus —カーネルスケジューラからCPUを分離します。

概要isolcpus = cpu_number [、cpu_number、...]

説明cpu_number値で定義されているように、指定されたCPUを一般的なカーネルSMPバランシングおよびスケジューラーのアルゴリズムから削除します。プロセスを「分離された」CPUに移動したり、分離したりする唯一の方法は、CPUアフィニティsyscallを使用することです。 cpu_numberは0から始まるため、最大値は、システム上のCPUの数よりも1少なくなります。

セットアップ方法を説明しようとしているこの構成は、テストよりもはるかに多くの用途があります。

たとえばMeruは、このテクノロジーをLinuxベースのAPコントローラーで使用して、ネットワークトラフィックがOSの内部動作、つまりI/O操作に干渉しないようにしています。

非常に忙しいWebフロントエンドでも使用していますが、まったく同じ理由があります。そのサーバーの好みがあまりに頻繁にコントロールを失っていることを人生経験から知りました。フロントエンドデーモンを専用のCPUで分離するまで、強制的に再起動する必要がありました。

8つのCPUがあるので、コマンドの出力で確認できます。

$ grep -c proc /proc/cpuinfo
8

または

$ lscpu | grep '^CPU.s'
CPU(s):                8

オプション/etc/default/grubのファイルGRUB_CMDLINE_LINUXにDebian/Ubuntuを追加します。

GRUB_CMDLINE_LINUX="isolcpus=7"

(0から始まり、8コアがあるため、7です)

次に実行します

Sudo update-grub

これは、カーネルにコアを使用しないように指示しています。

システムを再起動します。

次に、プロセスを開始します。

それを開始した直後に、8番目のCPU(0が1番目であるため7)に変更できます。そのCPUを使用しているのが自分だけであることを確認してください。

そのためには、次のコマンドを使用します。

taskset -cp 7 PID_number

taskset-プロセスのCPUアフィニティを取得または設定します

あらすじ

   taskset [options] [mask | list ] [pid | command [arg]...]

説明

tasksetは、PIDを指定して実行中のプロセスのCPUアフィニティを設定または取得するため、または特定のCPUアフィニティで新しいコマンドを起動するために使用されます。 CPUアフィニティは、システム上の特定のCPUセットにプロセスを「結合」するスケジューラプロパティです。 Linuxスケジューラは指定されたCPUアフィニティを尊重し、プロセスは他のCPUでは実行されません。 Linuxスケジューラは自然なCPUアフィニティもサポートしていることに注意してください。スケジューラは、パフォーマンス上の理由から実用的な限り、同じCPUでプロセスを維持しようとします。したがって、特定のCPUアフィニティを強制することは、特定のアプリケーションでのみ役立ちます。

詳細については、以下を参照してください。 isolcpus、numactl、taskset

また、ps -eFを使用すると、使用されているプロセッサがPSR列に表示されます。

私はCPU 2と3が分離されたサーバーを持っています。実際、ps -euserlandの唯一のプロセスで意図したとおりに表示できます。はpoundです。

# ps -eo psr,command | tr -s " " | grep "^ [2|3]"
 2 [cpuhp/2]
 2 [watchdog/2]
 2 [migration/2]
 2 [ksoftirqd/2]
 2 [kworker/2:0]
 2 [kworker/2:0H]
 3 [cpuhp/3]
 3 [watchdog/3]
 3 [migration/3]
 3 [ksoftirqd/3]
 3 [kworker/3:0]
 3 [kworker/3:0H]
 2 [kworker/2:1]
 3 [kworker/3:1]
 3 [kworker/3:1H]
 3 /usr/sbin/pound

それを非分離CPUと比較すると、それらはより多くのことを実行しています(下のウィンドウslides):

# ps -eo psr,command | tr -s " " | grep "^ [0|1]"
 0 init [2]
 0 [kthreadd]
 0 [ksoftirqd/0]
 0 [kworker/0:0H]
 0 [rcu_sched]
 0 [rcu_bh]
 0 [migration/0]
 0 [lru-add-drain]
 0 [watchdog/0]
 0 [cpuhp/0]
 1 [cpuhp/1]
 1 [watchdog/1]
 1 [migration/1]
 1 [ksoftirqd/1]
 1 [kworker/1:0]
 1 [kworker/1:0H]
 1 [kdevtmpfs]
 0 [netns]
 0 [khungtaskd]
 0 [oom_reaper]
 1 [writeback]
 0 [kcompactd0]
 0 [ksmd]
 1 [khugepaged]
 0 [crypto]
 1 [kintegrityd]
 0 [bioset]
 1 [kblockd]
 1 [devfreq_wq]
 0 [watchdogd]
 0 [kswapd0]
 0 [vmstat]
 1 [kthrotld]
 0 [kworker/0:1]
 0 [deferwq]
 0 [scsi_eh_0]
 0 [scsi_tmf_0]
 1 [vmw_pvscsi_wq_0]
 0 [bioset]
 1 [jbd2/sda1-8]
 1 [ext4-rsv-conver]
 0 [kworker/0:1H]
 1 [kworker/1:1H]
 1 [bioset]
 0 [bioset]
 1 [bioset]
 1 [bioset]
 1 [bioset]
 1 [bioset]
 1 [bioset]
 1 [bioset]
 0 [jbd2/sda3-8]
 1 [ext4-rsv-conver]
 1 /usr/sbin/rsyslogd
 0 /usr/sbin/irqbalance --pid=/var/run/irqbalance.pid
 1 /usr/sbin/cron
 0 /usr/sbin/sshd
 1 /usr/sbin/snmpd -Lf /dev/null -u snmp -g snmp -I -smux -p /var/run/snmpd.pid
 1 /sbin/getty 38400 tty1
 1 /lib/systemd/systemd-udevd --daemon
 0 /usr/sbin/xinetd -pidfile /run/xinetd.pid -stayalive
 1 [kworker/1:2]
 0 [kworker/u128:1]
 0 [kworker/0:2]
 0 [bioset]
 1 [xfsalloc]
 1 [xfs_mru_cache]
 1 [jfsIO]
 1 [jfsCommit]
 0 [jfsCommit]
 0 [jfsCommit]
 0 [jfsCommit]
 0 [jfsSync]
 1 [bioset]
 0 /usr/bin/monit -c /etc/monit/monitrc
 1 /usr/sbin/pound
 0 sshd: rui [priv]
 0 sshd: rui@pts/0,pts/1
 1 -bash
 1 -bash
 1 -bash
 1 [kworker/u128:0]
 1 -bash
 0 Sudo su
 1 su
 1 bash
 0 bash
 0 logger -t cmdline root[/home/rui] 
 1 ps -eo psr,command
 0 tr -s 
 0 grep ^ [0|1]
 0 /usr/bin/vmtoolsd
33
Rui F Ribeiro