it-swarm.com.de

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

Auf den ersten Blick scheint die Frage etwas albern/verwirrend zu sein, da das Betriebssystem die Prozessausführung verwaltet.

Ich möchte jedoch messen, wie stark einige Prozesse an CPU/E/A gebunden sind, und ich habe das Gefühl, dass mein Betriebssystem meine Experimente mit beispielsweise geplanten Betriebssystemprozessen beeinträchtigt.

Nehmen Sie als Beispiel die folgende Situation: Ich habe den Prozess A zweimal ausgeführt und die folgende Ausgabe vom Tool "Zeit" 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 (Diff. Von ~ 5 min), obwohl die Benutzer- und Systemzeit ähnlich sind. Das Gefühl, dass etwas in meiner Umgebung eine Art Streit verursacht hat.

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

Ich verwende Linux 4.4.0-45-generic mit buntu 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
31

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

isolcpus - Isoliert CPUs vom Kernel-Scheduler.

Synopsis isolcpus = cpu_number [ cpu_number, ...]

Beschreibung Entfernen Sie die angegebenen CPUs, wie durch die cpu_number-Werte definiert, aus den allgemeinen Kernel-SMP-Ausgleichs- und Scheduler-Algroithmen. 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, daher ist der Maximalwert 1 weniger als die Anzahl der CPUs im System.

Diese Konfiguration, die ich beschreiben möchte, kann weitaus mehr Verwendungszwecke haben als zum Testen.

Meru verwendet diese Technologie beispielsweise in seinen Linux-basierten AP-Controllern, um zu verhindern, dass der Netzwerkverkehr das Innenleben des Betriebssystems, nämlich den E/A-Betrieb, beeinträchtigt.

Ich verwende es aus den gleichen Gründen auch in einem sehr geschäftigen Web-Frontend: Ich habe aus meiner Lebenserfahrung herausgefunden, dass ich für meinen Geschmack dieses Servers zu regelmäßig die Kontrolle verloren habe. 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 anhand der Ausgabe des Befehls überprüfen:

$ grep -c proc /proc/cpuinfo
8

oder

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

Fügen Sie Debian/Ubuntu in der Datei /etc/default/grub Zur Option GRUB_CMDLINE_LINUX Hinzu:

GRUB_CMDLINE_LINUX="isolcpus=7"

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

Dann renne,

Sudo update-grub

Dies weist den Kernel an, keinen Ihrer Kerne zu verwenden.

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 sicher sein, dass Sie der einzige sind, der diese CPU verwendet.

Verwenden Sie dazu den folgenden Befehl:

taskset -cp 7 PID_number

task-Set - Abrufen oder Festlegen der CPU-Affinität eines Prozesses

ZUSAMMENFASSUNG

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

BESCHREIBUNG

das Task-Set wird verwendet, um die CPU-Affinität eines laufenden Prozesses anhand seiner PID festzulegen oder abzurufen oder um einen neuen BEFEHL mit einer bestimmten CPU-Affinität zu starten. Die CPU-Affinität ist eine Scheduler-Eigenschaft, die einen Prozess an einen bestimmten Satz von CPUs im System "bindet". Der Linux-Scheduler berücksichtigt die angegebene CPU-Affinität und der Prozess wird auf keiner anderen CPU 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 halten. Daher ist das Erzwingen einer bestimmten CPU-Affinität nur in bestimmten Anwendungen nützlich.

Weitere Informationen finden Sie unter: isolcpus, numactl und Task-Set

Auch mit ps -eF Sollten Sie in der PSR-Spalte den verwendeten Prozessor sehen.

Ich habe einen Server mit isolierten CPU 2 und 3, und tatsächlich kann er mit ps -e Als einzigem Prozess im Benutzerland wie beabsichtigt angezeigt werden ist 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 viele weitere Dinge (das Fenster unten 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: [email protected]/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