taskset: Configurando Afinidade de CPU no Linux
O Que Voce Vai Aprender
- Como fixar um processo em nucleos de CPU especificos com
taskset - A diferenca entre fixacao no inicio (
-c) e reatribuicao de um processo em execucao (-p) - Padroes praticos para benchmarking, isolamento de nucleos e NUMA
Resumo Rapido
- Fixar no inicio ->
taskset -c 0,1 ./program - Fixar um processo em execucao ->
taskset -cp 0-3 <PID> - Verificar estado atual ->
taskset -cp <PID> - A forma de lista (
-c) e legivel; a mascara hexadecimal serve para automacao
Pre-requisitos
tasksetvem com o pacoteutil-linux(pre-instalado na maioria das distros)- Numeros de nucleos comecam em
0. Conte-os comnproc - Alterar um processo em execucao requer ser dono do processo (ou
root)
O que e afinidade de CPU?
Conclusao: Afinidade de CPU restringe em quais nucleos de CPU um processo ou thread pode executar.
tasksete o comando para visualizar e alterar essa configuracao.
Por padrao, o escalonador do Linux pode mover um processo para qualquer nucleo ocioso. Configurar afinidade de CPU significa que o processo so pode executar nos nucleos que voce especificar.
As principais razoes para fixar sao:
- Localidade de cache: evitar invalidacao de cache L1/L2 causada por migracao de nucleo
- Isolamento de nucleo: dar a um processo sensivel a latencia um nucleo dedicado, livre de interferencia
- Benchmarks reprodutiveis: executar nos mesmos nucleos sempre para reduzir ruido nas medicoes
Afinidade especifica um conjunto de nucleos permitidos. Restrinja a um nucleo para fixacao rigida, ou permita varios e deixe o escalonador escolher dentro desse conjunto.
Verificar contagem e numeracao de nucleos
Conclusao: Antes de decidir onde fixar, confirme a contagem de nucleos disponiveis com
nproc. Numeros de nucleos comecam em0.
$ nproc
8
Se imprimir 8, numeros de nucleos validos sao 0-7. Especificar um nucleo inexistente como taskset -c 8 ... retorna um erro.
Use lscpu quando tambem precisar do layout fisico/logico.
$ lscpu
Fixar nucleos no inicio (-c)
Conclusao: Para fixar ao iniciar um comando, use
taskset -c <lista-nucleos> <comando>. A forma de lista aceita0,2(individual) e0-3(intervalo).
A forma basica: iniciar um novo processo fixado em nucleos especificos desde o inicio.
# Iniciar programa apenas nos nucleos 0 e 1 $ taskset -c 0,1 ./program # Iniciar no intervalo de nucleos 0 a 3 $ taskset -c 0-3 ./program # Fixar rigidamente em um unico nucleo (nucleo 2) $ taskset -c 2 ./program
-c (--cpu-list) permite listar numeros de nucleos diretamente, facilitando a leitura. Use , para nucleos individuais, - para intervalos, e combine ambos (por exemplo 0,2,4-7).
Passe opcoes ao comando iniciado adicionando-as normalmente.
taskset -c 0,1 stress-ng --cpu 2 funciona sem necessidade de separador --.
Visualizar e alterar um processo em execucao (-p)
Conclusao: Para um processo ja em execucao, use
-p(--pid):taskset -cp <PID>para verificar,taskset -cp <lista-nucleos> <PID>para alterar.
Verificar a afinidade atual
$ taskset -cp 1234
pid 1234's current affinity list: 0-7
0-7 significa "pode executar em todos os nucleos" (o padrao). Com -c voce obtem a forma de lista; sem ele, uma mascara hexadecimal.
Reatribuir um processo em execucao
# Reatribuir PID 1234 para nucleos 0 e 1 $ taskset -cp 0,1 1234
pid 1234's current affinity list: 0-7 pid 1234's new affinity list: 0,1
Encontre o PID com ps ou pgrep.
$ pgrep -f program
Atencao a ordem dos argumentos
No modo -p, a lista de nucleos vem primeiro, o PID depois: taskset -cp 0,1 1234, nao taskset -cp 1234 0,1. Invertendo, taskset trata o PID como mascara e falha.
Mascara hexadecimal vs forma de lista
Conclusao: Com
-cvoce especifica uma lista de nucleos; sem ele, uma mascara hexadecimal. Na mascara, cada bit mapeia um nucleo (bit 0 = nucleo 0).
Nativamente, taskset especifica nucleos como uma mascara hexadecimal. -c e a opcao que troca isso por uma lista legivel.
| Nucleos alvo | Forma de lista (-c) | Mascara hex |
|---|---|---|
| Nucleo 0 | 0 |
0x1 |
| Nucleos 0,1 | 0,1 |
0x3 |
| Apenas nucl 1 | 1 |
0x2 |
| Nucleos 0-3 | 0-3 |
0xf |
| Apenas nucl 3 | 3 |
0x8 |
A mascara e mais facil de ler em binario. O bit menos significativo (mais a direita) e o nucleo 0. 0x3 e 0b0011 (nucleos 0 e 1); 0x8 e 0b1000 (nucleo 3).
# Iniciar com mascara (nucleos 0,1 = 0x3) $ taskset 0x3 ./program # Verificar com mascara (sem -c) $ taskset -p 1234
pid 1234's current affinity mask: ff
Para comandos digitados manualmente, a forma de lista (-c) e mais segura. Um unico digito hexadecimal errado aponta para um nucleo diferente. Recorra a mascara apenas quando um script a gera.
Aplicar a todas as threads (-a)
Conclusao: Para fixar todas as threads de um processo multithread, adicione
-a(--all-tasks). Sem ele, apenas a thread principal e afetada.
Ao operar em um processo em execucao com -p, por padrao a afinidade se aplica apenas ao PID dado (a thread principal) e nao se propaga para threads filhas existentes. Use -a para fixar todas as threads do processo de uma vez.
# Fixar todas as threads do PID 1234 nos nucleos 0-3 $ taskset -acp 0-3 1234
Mesmo com -a, threads criadas apos a mudanca herdam a afinidade do processo. -a se aplica a threads existentes; threads futuras herdam de qualquer forma. Nao confunda os dois.
Casos de uso reais
Conclusao: Os casos classicos sao benchmarks reprodutiveis, isolamento de processos sensiveis a latencia e manter acesso a memoria local em NUMA.
Tornar benchmarks reprodutiveis
Medir nos mesmos nucleos toda vez remove a variancia de cache-miss causada por migracao de nucleo.
$ taskset -c 2,3 ./benchmark
Isolar processos sensiveis a latencia
Combine com o parametro de boot do kernel isolcpus, que remove nucleos do escalonador do SO, e entao coloque apenas seu processo alvo neles com taskset.
Manter memoria local em NUMA
Em sistemas NUMA, fixar em nucleos no mesmo no que a memoria evita acesso remoto a memoria. Quando tambem precisar controlar alocacao de memoria, numactl e mais adequado (taskset so lida com posicionamento de CPU).
A armadilha do excesso de fixacao
Fixe de forma muito agressiva e um processo nao podera usar outros nucleos ociosos, o que pode torna-lo mais lento. Fixe apenas apos medir e confirmar o beneficio. Nao fixe cegamente.
Erros comuns e solucoes
Conclusao: A maioria envolve um numero de nucleo inexistente, permissoes insuficientes ou ordem errada de argumentos.
sched_setaffinity: Invalid argument
Voce especificou um numero de nucleo que nao existe. Verifique o intervalo com nproc.
# Apenas 8 nucleos (0-7) existem mas nucleo 8 foi solicitado -> erro $ taskset -c 8 ./program
Operation not permitted
Voce esta tentando alterar o processo de outro usuario. Execute como o dono do processo ou use sudo.
$ sudo taskset -cp 0,1 1234
command not found: taskset
util-linux esta ausente (por exemplo, um container minimo). No Debian/Ubuntu, instale:
$ sudo apt install util-linux