O conjunto de tarefas não funciona em vários núcleos no isolcpus

12

Para prefácio, estou usando o Debian Wheezy com o kernel 3.2 em um chipset AMD64. Minha máquina possui dois núcleos Xeon E5-2690. Eu configurei os parâmetros de inicialização para que todos os núcleos em uma CPU sejam dedicados a um único processo. Para fazer isso, configurei isolcpus = 8,9,10,11,12,13,14,15 no grub.

Por enquanto, tudo bem. Agora, digamos que eu queira usar as CPUs isoladas para um determinado comando, para ser simples, usarei apenas um loop infinito simples:

$ taskset -c 8-15 bash -c 'enquanto verdadeiro; faça eco Olá> / dev / null; feito' &

Até agora, o top 8 mostra que o núcleo 8 gira até quase 100% de utilização. Agora, digamos que eu lance esse comando novamente:

$ taskset -c 8-15 bash -c 'enquanto verdadeiro; faça eco Olá> / dev / null; feito' &

Agora, o topo mostra que os núcleos 9 a 15 permanecem ociosos e os dois processos estão compartilhando o núcleo 8. Se, em vez disso, eu fizer isso:

$ taskset -c 8 bash -c 'enquanto verdadeiro; faça eco Olá> / dev / null; feito' &

$ taskset -c 9 bash -c 'enquanto verdadeiro; faça eco Olá> / dev / null; feito' &

Os núcleos 8 e 9 obtêm 100% de utilização como deveriam. Isso se aplica apenas ao isolcpus porque o mesmo conjunto de tarefas com os núcleos 1 a 7 distribui adequadamente os processos pelos núcleos relevantes. Além disso, "taskset -p" mostra que a máscara de afinidade para os processos de 8 a 15 está definida corretamente. Parece que o planejador do kernel se recusa a usar qualquer coisa, exceto o núcleo mais baixo especificado em uma máscara de afinidade isolcpus.

Agora, normalmente, isso não seria um grande problema com os exemplos acima, basta especificar núcleos individuais para cada processo. No entanto, eu quero executar um aplicativo altamente multithread na CPU dedicada. Desejo especificar o conjunto principal e fazer com que o pool de threads seja usado automaticamente, sem a necessidade de redefinir individualmente a afinidade do processador para cada segmento individual gerado.

Alguém tem alguma idéia de como fazer com que o agendador me dê mais de um núcleo do conjunto isolcpu?

user79126
fonte
você pode tentar usar um programa multithread? o bash não é multithread
c4f4t0r
1
Sim, foi originalmente o que me levou a perceber (meu programa multithread não estava usando mais de um núcleo). Um script python simples que cria muitos encadeamentos falha ao utilizar mais de um núcleo quando executado no conjunto isolcpus. (Quando executado nos núcleos não isolados, utiliza todos os 8 núcleos disponíveis).
user79126
leia este linuxtopia.org/online_books/linux_kernel/kernel_configuration/… , isso exclui um cpus do agendador do kernel, mas depois de excluir o cpus, você deseja executar o processo no cpus excluído?
C4f4t0r
1
O kernel não agendará um encadeamento ou processo no isolcpu, a menos que a máscara de afinidade do processador indique que deve ser usado. Caso contrário, isolcpus seria o mesmo que desligar o núcleo, quando o objetivo é reservar um núcleo por um motivo especificado pelo usuário e garantir que nenhum processo indesejado o utilize. O conjunto de tarefas define a máscara de afinidade para usar todos os núcleos no intervalo de 8 a 15 (que é definido corretamente quando marcado em / proc), para que o kernel esteja planejando o processo nos núcleos ociosos.
User79126

Respostas:

9

Após um dia de frustração, determinei uma solução. Esse comportamento parece ser um artefato do algoritmo padrão do agendador do kernel (SCHED_OTHER para esta distribuição / kernel). Alterar o processo para um algoritmo diferente elimina o problema; os isolcpus são utilizados adequadamente nos processos / threads.

Acabei usando SCHED_RR, mas também testei SCHED_FIFO e SCHED_IDLE, os quais parecem funcionar. O processo pode ser iniciado com o algoritmo alternativo usando o utilitário chrt:

$ sudo chrt -r 1 [comando]

(Se você deseja executar como não raiz, pode usar o utilitário setcap para ativar CAP_SYS_NICE no arquivo binário relacionado ao comando)

user79126
fonte
1
Embora a definição de tarefas de afinidade para núcleos 0,1, meu aplicativo java utilizasse apenas o primeiro núcleo. 'sudo chrt -r 1 [comando]' também resolveu o meu problema.
Barry NL