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

25

A princípio, a pergunta parece um pouco boba / confusa, pois o sistema operacional faz o trabalho de gerenciar a execução do processo.

No entanto, quero medir quanto alguns processos estão vinculados à CPU / IO e sinto que meu sistema operacional está interferindo em meus experimentos com, por exemplo, processos agendados do sistema operacional.

Tome como exemplo a seguinte situação: Executei o processo A duas vezes e obtive a seguinte saída da ferramenta "time" (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 semelhante, o tempo decorrido de ambas muda drasticamente (diferença de ~ 5 min). Parece que algo no meu ambiente causou algum tipo de disputa.

Quero interromper todos os processos / serviços possíveis para evitar qualquer tipo de ruído durante meus experimentos, mas 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 64 bits.

Eu realmente aprecio a assistência. Se vocês precisarem de alguma informação que falta, editarei imediatamente minha postagem.

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
Jeanderson Candido
fonte
Você pode iniciar seu processo usando uma alta prioridadenice -19 process
Dababi

Respostas:

26

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

isolcpus - isola CPUs do agendador do kernel.

Sinopse isolcpus = cpu_number [, cpu_number, ...]

Descrição Remova as CPUs especificadas, conforme definido pelos valores cpu_number, dos algoritmos gerais de balanceamento e agendador SMP do kernel. A única maneira de mover um processo para dentro ou para fora de uma CPU "isolada" é através dos syscalls de afinidade da CPU. cpu_number começa em 0, portanto, o valor máximo é 1 menor que o número de CPUs no sistema.

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

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

Também o uso em um front-end da web muito ocupado, pelas mesmas razões: descobri por experiência de vida que perdi o controle com muita regularidade para o gosto desse servidor; tive que reiniciá-lo com força até eu separar o daemon de front-end em seus próprios processadores dedicados.

Como você possui 8 CPUs, é possível 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à opção GRUB_CMDLINE_LINUX:

GRUB_CMDLINE_LINUX="isolcpus=7"

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

Então corra,

sudo update-grub

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

Reinicie o sistema.

Então inicie seu processo.

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

Para isso, use o comando:

taskset -cp 7 PID_number

conjunto de tarefas - recuperar ou definir a afinidade da CPU de um processo

SINOPSE

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

DESCRIÇÃO

O conjunto de tarefas é usado para definir ou recuperar a afinidade da CPU de um processo em execução, devido ao seu PID ou para lançar um novo COMMAND com uma determinada afinidade da CPU. A afinidade da CPU é uma propriedade do planejador que "liga" um processo a um determinado conjunto de CPUs no sistema. O planejador do Linux respeitará a afinidade da CPU fornecida e o processo não será executado em nenhuma outra CPU. Observe que o planejador Linux também suporta afinidade natural da CPU: o planejador tenta manter os processos na mesma CPU desde que seja prático por motivos de desempenho. Portanto, forçar uma afinidade específica da CPU é útil apenas em certos aplicativos.

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

Também usando ps -eFvocê deve ver na coluna PSR o processador que está sendo usado.

Eu tenho um servidor com CPU 2 e 3 isolado e, de fato, pode ser visto com ps -eo único processo na terra do usuário, 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 as CPUs não isoladas, elas 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
Rui F Ribeiro
fonte
Eu não sabia que era possível fazer isso :) Vou verificar suas referências. Olhando para a frente para marcar este tópico como resolvido;)
Jeanderson Candido
Eu quase esqueci ... existe alguma maneira de monitorar a execução para verificar se esse isolamento funciona?
Jeanderson Candido
Você é bem vindo. Adicionada uma pequena introdução como o segundo parágrafo. Note que eu tenho visto alguns tutorial na conversa net sobre taskset, mas muitas vezes eles não mencionam junto com eleisolcpus
Rui F Ribeiro