Como se pode restringir o número de núcleos de CPU que cada usuário pode usar?


17

Temos um computador cuja CPU possui 32 núcleos e será usada para executar programas por alguns usuários diferentes. Existe alguma maneira de restringir o número de núcleos que cada usuário pode usar a qualquer momento para que um usuário não monopolize toda a energia da CPU?


5
Não é uma resposta, apenas uma ideia. Você pode querer configurar várias máquinas virtuais. Cada um pode ter apenas uma quantidade limitada de CPU-s. Cada usuário estaria apenas em uma das máquinas virtuais e os usuários nessa VM seriam limitados no uso da CPU. Pode ser que alguns dos softwares de virtualização possuam ferramentas para dar suporte a isso.
— precisa saber é o seguinte

11
@ghellquist você deve fazer que uma resposta
— slebetman

@ghellquist: Você provavelmente quer algo o mais leve possível, como contêineres Linux, se quiser que usuários diferentes vejam apenas algumas das CPUs. (por exemplo, quando eles iniciam um OpenMP ou outro programa que inicia o número de threads que vê núcleos, ele inicia um número apropriado para a quantidade de núcleos que você está deixando que cada usuário realmente use). A virtualização completa, como o KVM, tem um custo de desempenho, mesmo com suporte de hardware como o VT-X ou o AMD-V, a partir de níveis extras de tabelas de páginas, mesmo quando as saídas da VM são evitadas, em código que causa falta de TLB ao tocar em muita memória.
— Peter Cordes

Sinto muito, mas há alguma necessidade disso? Como um sistema multiusuário, por padrão, o Linux já implementa multitarefas preemptivas, portanto a situação em que um único usuário (não malicioso) apenas monopoliza todo o sistema por si só não deve aparecer.
— cúbico

Respostas:


16

Embora isso seja possível , é complicado e quase certamente uma má ideia. Se apenas um usuário estiver usando a máquina no momento, restringi-los a N núcleos é um desperdício de recursos. Uma abordagem muito melhor seria executar tudo com nice:

NAME
       nice - run a program with modified scheduling priority

SYNOPSIS
       nice [OPTION] [COMMAND [ARG]...]

DESCRIPTION
       Run  COMMAND  with an adjusted niceness, which affects process scheduling.  With
       no COMMAND, print the current niceness.  Niceness values range  from  -20  (most
       favorable to the process) to 19 (least favorable to the process).

Essa é uma ótima ferramenta que define a prioridade de um processo. Portanto, se apenas um usuário estiver executando alguma coisa, eles terão o tempo de CPU necessário, mas se outra pessoa iniciar seu próprio trabalho (também é necessário), eles serão agradáveis ​​e compartilharão um com o outro. Dessa forma, se todos os seus usuários iniciarem comandos nice 10 command, ninguém estará consumindo recursos (e ninguém trará o servidor de joelhos).

Observe que um valor alto e agradável significa baixa prioridade. Essa é uma medida de quão legais devemos ser e quanto mais agradáveis ​​somos, mais compartilhamos.

Observe também que isso não ajudará a gerenciar a alocação de memória, mas afeta apenas o agendamento da CPU. Portanto, se vários usuários iniciarem vários processos com muita memória, você ainda terá um problema. Se isso é um problema, você deve procurar sistemas de filas adequados, como torque .


Obrigado pela sua resposta. Existem alguns "gerenciadores de carga de trabalho", como o SLURM, mas são para computadores com vários nós. Acho que faz sentido que as pessoas não tenham desenvolvido aplicativos semelhantes para computadores de nó único, pois não há tanta demanda.
— Reza

@Reza tente nice, pelo que você descreve, é exatamente o que você precisa.
— terdon 9/01/19

3
@Reza: Isso porque o sistema operacional já faz isso. Ele compartilha automaticamente as CPUs disponíveis em threads / processos, conforme necessário.
— BlueRaja - Danny Pflughoeft

13

TL; DR : a partir de uma breve pesquisa, parece que é possível restringir os comandos a um número específico de núcleos; no entanto, em todos os casos, é necessário usar um comando que realmente imponha a restrição.

cgroups

O Linux possui o cgroupsque é freqüentemente usado exatamente com a finalidade de restringir os recursos disponíveis para os processos. De uma pesquisa muito breve, você pode encontrar um exemplo no Arch Wiki com a configuração do Matlab (um software científico) definida em /etc/cgconfig.conf:

group matlab {
    perm {
        admin {
            uid = username;
        }
        task {
            uid = username;
        }
    }

    cpuset {
        cpuset.mems="0";
        cpuset.cpus="0-5";
    }
    memory {
        memory.limit_in_bytes = 5000000000;
    }
}

Para que essa configuração entre em vigor, você deve executar o processo via cgexeccomando, por exemplo, na mesma página da wiki:

$ cgexec -g memory,cpuset:matlab /opt/MATLAB/2012b/bin/matlab -desktop

conjunto de tarefas

Uma pergunta relacionada ao Ask Ubuntu e Como limitar um processo a um núcleo de CPU no Linux? [duplicado] no site Unix e Linux mostra um exemplo de uso tasksetpara limitar as CPUs do processo. Na primeira pergunta, isso é alcançado através da análise de todos os processos para um usuário específico

$ ps aux | awk '/^housezet/{print $2}' | xargs -l taskset -p 0x00000001

Na outra questão, um processo é iniciado via tasksetele mesmo:

$ taskset -c 0 mycommand --option  # start a command with the given affinity

Conclusão

Embora seja certamente possível limitar processos, parece que não é tão simples conseguir isso para usuários específicos. O exemplo na postagem Ask Ubuntu vinculada exigiria uma verificação consistente dos processos pertencentes a cada usuário e usados tasksetem cada novo. Uma abordagem muito mais razoável seria executar seletivamente aplicativos intensivos da CPU, via cgexecou taskset; também não faz sentido restringir todos os processos a um número específico de CPUS, especialmente para aqueles que realmente usam paralelismo e simultaneidade para executar suas tarefas mais rapidamente - limitá-los a um número específico de CPUs pode ter o efeito de retardar o processamento. Além disso, como a resposta de Terdon mencionou, é um desperdício de recursos

A execução de aplicativos selecionados via tasksetou cgexecrequer a comunicação com seus usuários para que eles saibam quais aplicativos eles podem executar ou a criação de scripts de wrapper que iniciarão aplicativos selecionados via taskselou cgexec.

Além disso, considere definir o número de processos que um usuário ou grupo pode gerar em vez de definir o limite do número de CPUs. Isso pode ser conseguido via /etc/security/limits.confarquivo .

Veja também


11
bem, existe o cgrulesengd e o cgrules.conf para mover automaticamente os processos para o cgroup apropriado com base no usuário / grupo, em vez de confiar nos usuários que executam seus processos com o cgexec. Mas parece que configurá-lo no ubuntu não é nada trivial.
— Hans-Jakob

@ Hans-Jakob Parece um pouco complicado, além de exigir a adição de sinalizadores de kernel no GRUB. Provavelmente para máquinas de nível corporativo, onde você tem muitos usuários e não deseja que eles travem o sistema, isso provavelmente vale a pena, mas para desktop - muito trabalho. Obrigado por vincular isso.
— Sergiy Kolodyazhnyy 9/01/19

2
sched_setaffinity(2)diz a máscara de afinidade é preservada em todo execve(2), e que uma criança herda on fork(2). Portanto, se você definir o shell para um usuário (ou o shell gráfico para uma sessão X), tudo o que iniciar nesse shell usará, por padrão, a mesma máscara de afinidade.
— Peter Cordes

11
Uma desvantagem possível são os programas que verificam quantas CPUs a máquina possui ao decidir quantos threads iniciar; eles terão muitos threads para o número de núcleos nos quais serão agendados. Você descobriu se o cgroups pode fazer algo sobre isso?
— Peter Cordes

@PeterCordes A ideia da concha desova parece interessante. Vou precisar investigar isso. Obrigado ! Quanto ao segundo comentário, não, eu não pesquisei cgroups o suficiente neste momento.
— Sergiy Kolodyazhnyy 10/01/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.