Wie kann die exklusive CPU-Verfügbarkeit für einen laufenden Prozess sichergestellt werden?

25

Zunächst scheint die Frage ein wenig albern / verwirrend zu sein, da das Betriebssystem die Prozessausführung verwaltet.

Ich möchte jedoch messen, inwieweit einige Prozesse CPU / IO-gebunden sind, und ich habe das Gefühl, dass mein Betriebssystem meine Experimente mit beispielsweise geplanten Betriebssystemprozessen stört.

Nehmen Sie als Beispiel die folgende Situation: Ich habe den Prozess A zweimal ausgeführt und vom Tool "time" die folgende Ausgabe erhalten (Zeitspalten in Sekunden):

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

Wie wir sehen können, ändert sich die verstrichene Zeit beider drastisch (Unterschied von ~ 5 Minuten), obwohl die Benutzer- und Systemzeit ähnlich sind. Das Gefühl, etwas in meiner Umgebung zu haben, verursachte eine Art Streit.

Ich möchte alle möglichen Hintergrundprozesse / -dienste stoppen, um jegliche Art von Lärm während meiner Experimente zu vermeiden, aber ich betrachte mich als Anfänger / fortgeschrittener Unix-Benutzer und weiß nicht, wie ich dies garantieren kann.

Ich benutze Linux 4.4.0-45-generic mit Ubuntu 14.04 LTS 64 Bit.

Ich schätze die Hilfe sehr. Wenn ihr fehlende Informationen benötigt, werde ich meinen Beitrag umgehend bearbeiten.

CPU Info

$ 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
Jeanderson Candido
quelle
Sie können Ihren Prozess mit einer hohen Priorität nice -19 process
starten

Antworten:

26

Sie haben eine Kerneloptionskonfiguration, bei der eine CPU nicht vom Betriebssystem verwendet wird isolcpus.

isolcpus - Isolieren Sie CPUs vom Kernel-Scheduler.

Inhaltsangabe isolcpus = cpu_number [, cpu_number, ...]

Beschreibung Entfernen Sie die angegebenen CPUs, wie durch die Werte für cpu_number definiert, aus den allgemeinen SMP-Balancing- und Scheduler-Algorithmen des Kernels. Die einzige Möglichkeit, einen Prozess auf eine "isolierte" CPU zu verschieben oder von dieser zu entfernen, besteht in den CPU-Affinitätssystemaufrufen. cpu_number beginnt bei 0, der Maximalwert ist also 1 weniger als die Anzahl der CPUs im System.

Diese Konfiguration, die ich kurz beschreiben werde, kann weit mehr als nur zum Testen verwendet werden.

Meru verwendet diese Technologie beispielsweise in seinen Linux-basierten AP-Controllern, um zu verhindern, dass der Netzwerkverkehr das Innenleben des Betriebssystems, dh die E / A-Vorgänge, beeinträchtigt.

Ich benutze es auch in einem stark frequentierten Web-Frontend, und zwar aus genau den gleichen Gründen: Ich habe aus meiner Lebenserfahrung herausgefunden, dass ich die Kontrolle über diesen Server zu regelmäßig verloren habe, um meinen Geschmack zu finden. musste es gewaltsam neu starten, bis ich den Front-End-Daemon auf seinen eigenen dedizierten CPUs trennte.

Da Sie 8 CPUs haben, können Sie dies mit der Ausgabe des Befehls überprüfen:

$ grep -c proc /proc/cpuinfo
8

oder

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

Fügen Sie in Debian / Ubuntu in der Datei /etc/default/grubFolgendes hinzu GRUB_CMDLINE_LINUX:

GRUB_CMDLINE_LINUX="isolcpus=7"

(es ist 7, weil es mit 0 beginnt und Sie 8 Kerne haben)

Dann renne,

sudo update-grub

Dies bedeutet, dass der Kernel keinen Ihrer Kerne verwenden soll.

Starten Sie das System neu.

Dann starten Sie Ihren Prozess.

Unmittelbar nach dem Start können Sie für die 8. CPU wechseln (7, da 0 die 1. ist), und Sie müssen ganz sicher sein, dass Sie die einzige sind, die diese CPU verwendet.

Verwenden Sie dazu den Befehl:

taskset -cp 7 PID_number

Taskset - Ruft die CPU-Affinität eines Prozesses ab oder legt sie fest

ZUSAMMENFASSUNG

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

BESCHREIBUNG

Taskset dient zum Festlegen oder Abrufen der CPU-Affinität eines laufenden Prozesses anhand seiner PID oder zum Starten eines neuen Befehls mit einer bestimmten CPU-Affinität. CPU-Affinität ist eine Scheduler-Eigenschaft, die einen Prozess an eine bestimmte Gruppe von CPUs im System "bindet". Der Linux-Scheduler berücksichtigt die angegebene CPU-Affinität und der Prozess wird auf keinen anderen CPUs ausgeführt. Beachten Sie, dass der Linux-Scheduler auch die natürliche CPU-Affinität unterstützt: Der Scheduler versucht, Prozesse aus Leistungsgründen so lange wie möglich auf derselben CPU zu belassen. Daher ist das Erzwingen einer bestimmten CPU-Affinität nur in bestimmten Anwendungen sinnvoll.

Weitere Informationen finden Sie unter: isolcpus, numactl und taskset

Außerdem ps -eFsollten Sie in der PSR-Spalte den verwendeten Prozessor sehen.

Ich habe einen Server mit CPU 2 und 3 isoliert, und in der Tat ist es mit ps -edem einzigen Prozess im Userland, wie beabsichtigt, zu sehen 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

Wenn Sie es mit den nicht isolierten CPUs vergleichen, laufen auf ihnen noch viele andere Dinge (das Fenster unter den Folien ):

# 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
Rui F Ribeiro
quelle
Ich wusste nicht, dass das möglich ist :) Ich werde Ihre Referenzen überprüfen. Ich freue mich darauf, diesen Thread als gelöst zu markieren;)
Jeanderson Candido
Fast hätte ich vergessen ... gibt es eine Möglichkeit, die Ausführung zu überwachen, um zu überprüfen, ob diese Isolation funktioniert?
Jeanderson Candido
Bitte schön. Ein kleines Intro als 2. Absatz hinzugefügt. Beachten Sie, dass ich einige Tutorials im Internet gesehen habe, in denen es um Aufgaben geht, aber sie werden oft nicht zusammen erwähntisolcpus
Rui F Ribeiro