¿Cómo garantizar la disponibilidad exclusiva de la CPU para un proceso en ejecución?

25

Al principio, la pregunta parece ser un poco tonta / confusa ya que el sistema operativo hace el trabajo de administrar la ejecución del proceso.

Sin embargo, quiero medir cuánto están vinculados algunos procesos con CPU / IO y siento que mi sistema operativo está interfiriendo en mis experimentos con, por ejemplo, procesos de sistema operativo programados.

Tomemos como ejemplo la siguiente situación: ejecuté el proceso A dos veces y obtuve el siguiente resultado de la herramienta "tiempo" (columnas de tiempo en segundos):

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

Como podemos ver, aunque el usuario y el tiempo del sistema son similares, el tiempo transcurrido de ambos cambia drásticamente (dif. De ~ 5 min). Parece que algo en mi entorno causó algún tipo de disputa.

Quiero detener todos los procesos / servicios en segundo plano posibles para evitar cualquier tipo de ruido durante mis experimentos, pero me considero un usuario novato / intermedio de Unix y no sé cómo garantizarlo.

Estoy usando Linux 4.4.0-45-generic con Ubuntu 14.04 LTS de 64 bits.

Realmente aprecio la ayuda. Si necesitan información faltante, editaré mi publicación de inmediato.

Información de la 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
Jeanderson Candido
fuente
Puede comenzar su proceso con una alta prioridadnice -19 process
Dababi,

Respuestas:

26

Tiene una configuración de opción de núcleo donde el sistema operativo no utilizará una CPU, se llama isolcpus.

isolcpus: aísla las CPU del planificador del núcleo.

Sinopsis isolcpus = cpu_number [, cpu_number, ...]

Descripción Elimine las CPU especificadas, según lo definido por los valores de cpu_number, de los algoritmos generales de equilibrio y planificador SMP del núcleo. La única forma de mover un proceso dentro o fuera de una CPU "aislada" es a través de las llamadas al sistema de afinidad de la CPU. cpu_number comienza en 0, por lo que el valor máximo es 1 menos que el número de CPU en el sistema.

Esta configuración que estoy a punto de describir cómo configurar, puede tener muchos más usos que para las pruebas.

Meru, por ejemplo, utiliza esta tecnología en sus controladores AP basados ​​en Linux, para evitar que el tráfico de la red interfiera con el funcionamiento interno del sistema operativo, es decir, las operaciones de E / S.

También lo uso en una interfaz web muy ocupada, por las mismas razones: descubrí por experiencia que perdí el control con demasiada frecuencia para mi gusto por ese servidor; tuve que reiniciarlo con fuerza hasta que separé el demonio front-end en sus propias CPU dedicadas.

Como tiene 8 CPU, que puede verificar con la salida del comando:

$ grep -c proc /proc/cpuinfo
8

o

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

Agregue Debian / Ubuntu en el archivo /etc/default/gruba la opción GRUB_CMDLINE_LINUX:

GRUB_CMDLINE_LINUX="isolcpus=7"

(es 7, porque comienza en 0 y tiene 8 núcleos)

Entonces corre,

sudo update-grub

Esto le dice al núcleo que no use uno de sus núcleos.

Reinicia el sistema.

Entonces comienza tu proceso.

Inmediatamente después de iniciarlo, puede cambiar para la octava CPU (7 porque 0 es la primera) y estar seguro de que es la única que usa esa CPU.

Para eso, usa el comando:

taskset -cp 7 PID_number

conjunto de tareas: recuperar o establecer la afinidad de CPU de un proceso

SINOPSIS

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

DESCRIPCIÓN

El conjunto de tareas se utiliza para establecer o recuperar la afinidad de CPU de un proceso en ejecución dado su PID o para lanzar un nuevo COMANDO con una afinidad de CPU dada. La afinidad de la CPU es una propiedad del planificador que "vincula" un proceso a un conjunto determinado de CPU en el sistema. El programador de Linux respetará la afinidad de CPU dada y el proceso no se ejecutará en ninguna otra CPU. Tenga en cuenta que el planificador de Linux también es compatible con la afinidad natural de la CPU: el planificador intenta mantener los procesos en la misma CPU siempre que sea práctico por razones de rendimiento. Por lo tanto, forzar una afinidad de CPU específica es útil solo en ciertas aplicaciones.

Para leer más sobre esto, vea: isolcpus, numactl y taskset

También ps -eFdebe ver en la columna PSR el procesador que se está utilizando.

Tengo un servidor con CPU 2 y 3 aisladas, y de hecho, se puede ver con ps -eel único proceso en el país de usuario según lo previsto 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

Si lo compara con las CPU no aisladas, están ejecutando muchas más cosas (la ventana siguiente se desliza ):

# 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
fuente
No sabía que era posible hacer eso :) Voy a verificar sus referencias. Mirando hacia adelante para marcar este hilo como resuelto;)
Jeanderson Candido
Casi se me olvida ... ¿hay alguna forma de monitorear la ejecución para verificar si este aislamiento funciona?
Jeanderson Candido
De nada. Se agregó una pequeña introducción como el segundo párrafo. Tenga en cuenta que he visto un tutorial en la red hablando sobre el conjunto de tareas, pero a menudo no lo mencionan junto con élisolcpus
Rui F Ribeiro