Como garantir a disponibilidade exclusiva da CPU para um processo em execução?

15

A princípio, a questão parece ser um pouco tola / confusa, já que o SO faz o trabalho de gerenciar a execução do processo.

No entanto, quero medir o quanto alguns processos estão ligados à CPU / IO e sinto que meu sistema operacional está interferindo em minhas experiências com, por exemplo, processos agendados do sistema operacional.

Tome como exemplo a seguinte situação: Eu executei o processo A duas vezes e obtive a seguinte saída da ferramenta "tempo" (colunas de tempo em 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, embora o tempo do usuário e do sistema seja similar, o tempo decorrido de ambos muda drasticamente (diferença de ~ 5 min). Parece que algo no meu ambiente causou algum tipo de contenção.

Eu quero parar todos os possíveis processos / serviços em segundo plano para evitar qualquer tipo de ruído durante meus experimentos, mas eu me considero um usuário unix novato / intermediário e não sei como garantir isso.

Estou usando o Linux 4.4.0-45-generic com o Ubuntu 14.04 LTS de 64 bits.

Eu realmente agradeço a ajuda. Se vocês precisarem de alguma informação que esteja faltando, eu prontamente editarei meu post.

Informações da 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
    
por Jeanderson Candido 28.11.2016 / 15:17

1 resposta

19

Você tem uma configuração de opção do kernel em que uma CPU não será usada pelo sistema operacional, é chamada de isolcpus .

isolcpus — Isolate CPUs from the kernel scheduler.

Synopsis isolcpus= cpu_number [, cpu_number ,...]

Description Remove the specified CPUs, as defined by the cpu_number values, from the general kernel SMP balancing and scheduler algroithms. The only way to move a process onto or off an "isolated" CPU is via the CPU affinity syscalls. cpu_number begins at 0, so the maximum value is 1 less than the number of CPUs on the system.

Esta configuração estou prestes a descrever como configurar, pode ter muito mais usos do que para testes.

O Meru, por exemplo, usa essa tecnologia em seus controladores AP baseados em Linux, para impedir que o tráfego da rede interfira com o funcionamento interno do sistema operacional, chamado de operações de E / S.

Eu também o uso em um front-end web muito ocupado, pelas mesmas razões: Descobri da experiência de vida que perdi o controle muito regularmente para o gosto daquele servidor; tive que reiniciá-lo com força até que eu separei o daemon front end em suas próprias CPUs dedicadas.

Como você tem 8 CPUs, você pode verificar com a saída do comando:

$ grep -c proc /proc/cpuinfo
8

ou

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

Adicione no Debian / Ubuntu no arquivo /etc/default/grub a opção GRUB_CMDLINE_LINUX :

GRUB_CMDLINE_LINUX="isolcpus=7"

(é 7, porque começa em 0 e você tem 8 núcleos)

Em seguida, execute

sudo update-grub

Isso está dizendo ao kernel para não usar um de seus núcleos.

Reinicie o sistema.

Em seguida, inicie seu processo.

Imediatamente após iniciá-lo, você pode mudar para a 8ª CPU (7 porque 0 é a 1ª) e ter certeza de que você é o único que usa essa CPU.

Para isso, use o comando:

taskset -cp 7 PID_number

taskset - retrieve or set a processes’s CPU affinity

SYNOPSIS

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

DESCRIPTION

taskset is used to set or retrieve the CPU affinity of a running pro cess given its PID or to launch a new COMMAND with a given CPU affinity. CPU affinity is a scheduler property that "bonds" a process to a given set of CPUs on the system. The Linux scheduler will honor the given CPU affinity and the process will not run on any other CPUs. Note that the Linux scheduler also supports natural CPU affinity: the scheduler attempts to keep processes on the same CPU as long as practical for performance reasons. Therefore, forcing a specific CPU affinity is useful only in certain applications.

Para ler mais sobre isso, consulte: isolcpus, numactl e taskset

Usando também ps -eF você deve ver na coluna PSR o processador que está sendo usado.

Eu tenho um servidor com CPU 2 e 3 isolado e, de fato, ele pode ser visto com ps -e o único processo em userland como pretendido, é 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

Se você compará-lo com os processadores não isolados, eles estão executando muito mais coisas (a janela abaixo 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
    
por 28.11.2016 / 15:44