O que faz um processo de CPU inativo?

68

Eu sei que isso parece absurdo, algo "ocioso" deve permanecer ocioso e não fazer nada, mas por favor, tenha paciência comigo.

Olhando para a fonte de strace , encontrei o uso da bandeira clone CLONE_IDLETASK , que é descrito como:

#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */

Depois de analisar mais profundamente, descobri que, embora essa sinalização não seja coberta em man clone , ela é usada pelo kernel durante o processo de boot para criar processos inativos (todos devem ter PID 0) para cada CPU em a máquina. ou seja, uma máquina com 8 CPUs terá pelo menos 7 (veja a pergunta abaixo) tais processos "em execução" (note aspas).

Agora, isso me leva a algumas perguntas sobre o que esse processo "inativo" realmente faz. Minha suposição é que ele executa a operação NOP continuamente até que seu período termine e o kernel atribua um processo real para executar ou designar o processo ocioso novamente (se a CPU não estiver sendo usada). No entanto, isso é um palpite completo. Então:

  1. Em uma máquina com, digamos, 8 CPUs, 7 desses processos ociosos serão criados? (e uma CPU será mantida pelo próprio kernel enquanto nenhum trabalho do userspace em execução?)

  2. O processo ocioso é realmente apenas um fluxo infinito de operações NOP? (ou um loop que faz o mesmo).

  3. O uso da CPU (por exemplo, uptime ) é calculado simplesmente por quanto tempo o processo inativo estava na CPU e por quanto tempo ele não estava lá durante um determinado período de tempo?

P.S. É provável que boa parte dessa questão se deva ao fato de eu não entender completamente como funciona uma CPU. Ou seja, eu entendo a montagem, os prazos e as interrupções, mas não sei como, por exemplo, uma CPU pode usar mais ou menos energia, dependendo do que está sendo executado. Eu ficaria grato se alguém puder me esclarecer sobre isso também.

    
por grochmal 25.04.2017 / 20:09

3 respostas

80

A tarefa ociosa é usada para contabilidade de processo e também para reduzir o consumo de energia. No Linux, uma tarefa ociosa é criada para cada processador e bloqueada para esse processador; sempre que não houver outro processo para ser executado nessa CPU, a tarefa ociosa será agendada. O tempo gasto nas tarefas ociosas aparece como tempo "inativo" em ferramentas como top . (O tempo de atividade é calculado de forma diferente.)

O Unix parece sempre ter um loop ocioso de algum tipo (mas não necessariamente uma tarefa ociosa real, consulte resposta de Gilles ), e mesmo em V1 usado uma instrução WAIT que parou o processador até que ocorresse uma interrupção (significava “wait for interrupt”). Alguns outros sistemas operacionais usavam loops ocupados, DOS, OS / 2 , e versões antigas do Windows em particular. Por muito tempo agora, os processadores usaram esse tipo de instrução de "espera" para reduzir o consumo de energia e a produção de calor. Você pode ver várias implementações de tarefas ociosas, por exemplo, em arch/x86/kernel/process.c no kernel Linux: o básico apenas chama HLT , que pára o processador até que ocorra uma interrupção (e ativa o modo de economia de energia C1), as outras implementações lidam com vários erros ou ineficiências ( por exemplo usando MWAIT em vez de HLT em algumas CPUs).

Tudo isso é completamente separado dos estados ociosos nos processos, quando eles aguardam por um evento (I / O etc.).

    
por 25.04.2017 / 20:43
46

No design de livro didático de um agendador de processo, se o agendador não tiver nenhum processo para agendar (ou seja, se todos os processos estiverem bloqueados, aguardando entrada), o agendador aguardará uma interrupção do processador. A interrupção pode indicar a entrada de um periférico (ação do usuário, pacote de rede, leitura completa de um disco, etc.) ou pode ser uma interrupção de timer que aciona um timer em um processo.

O programador do Linux não possui código especial para um caso "nada a fazer". Em vez disso, ele codifica o caso "nada a fazer" como um processo especial, o processo ocioso. O processo ocioso só é agendado quando nenhum outro processo é escalonável (ele efetivamente tem uma prioridade infinitamente baixa). O processo inativo é, na verdade, parte do kernel: é um encadeamento do kernel, ou seja, um encadeamento que executa código no kernel, em vez de código em um processo. (Mais precisamente, há um desses threads para cada CPU.) Quando o processo ocioso é executado, ele executa a operação de espera por interrupção.

Como funciona a espera por interrupção depende dos recursos do processador. Com o design de processador mais básico, isso é apenas um loop ocupado -

nothing:
    goto nothing

O processador continua executando uma instrução de ramificação para sempre, o que não realiza nada. A maioria dos sistemas operacionais modernos não faz isso, a menos que eles estejam rodando em um processador onde não há nada melhor, e a maioria dos processadores tem algo melhor. Em vez de gastar energia sem fazer nada, exceto aquecer a sala, idealmente, o processador deve ser desligado. Assim, o kernel executa o código que instrui o processador a se desligar ou, pelo menos, a desligar a maior parte do processador. Deve haver pelo menos uma pequena parte que fica ligada, o controlador de interrupção. Quando um periférico dispara uma interrupção, o controlador de interrupção envia um sinal de despertar para o processador principal (parte do).

Na prática, CPUs modernas como Intel / AMD e ARM possuem muitas configurações complexas de gerenciamento de energia. O sistema operacional pode estimar quanto tempo o processador permanecerá no modo ocioso e escolherá diferentes modos de baixo consumo dependendo disso. Os modos oferecem diferentes compromissos entre o uso de energia enquanto ocioso e o tempo necessário para entrar e sair do modo inativo. Em alguns processadores, o sistema operacional também pode diminuir o clock do processador quando descobre que os processos não estão consumindo muito tempo da CPU.

    
por 26.04.2017 / 01:04
0

Não, uma tarefa inativa não desperdiça os ciclos da CPU. O agendador simplesmente não seleciona um processo ocioso para execução. Um processo ocioso está aguardando algum evento para que ele possa continuar. Por exemplo, pode estar aguardando uma entrada em uma chamada de sistema read() .

A propósito, o kernel não é um processo separado. O código do kernel é sempre executado no contexto de um processo (bem, exceto pelo caso especial de um encadeamento do kernel), portanto não é correto dizer "e uma CPU será mantida pelo próprio kernel enquanto não houver trabalho no espaço do usuário". / p>     

por 25.04.2017 / 20:23