O que faz um processo inativo da CPU?

73

Olhando para a fonte strace, encontrei o uso da bandeira do clone, CLONE_IDLETASKque é descrita como:

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

Depois de analisar mais detalhadamente, descobri que, embora esse sinalizador não seja coberto, man cloneele é realmente usado pelo kernel durante o processo de inicialização para criar processos inativos (todos com PID 0) para cada CPU na máquina. isto é, uma máquina com 8 CPUs terá pelo menos 7 (veja a pergunta abaixo) esses processos "em execução" (aspas).

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

  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 espaço do usuário estiver funcionando?)

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

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


PS É provável que boa parte dessa pergunta se deva ao fato de eu não entender completamente como uma CPU funciona. 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á executando. Ficaria muito grato se alguém puder me esclarecer sobre isso também.

grochmal
fonte
17
Eu tive que resistir à tentação de escrever "Nada" quando vi o título.
Validade 26/04
4
As CPUs mais modernas reduzirão dinamicamente sua taxa de clock e consumo de energia quando estiverem ociosas ou sob carga baixa ( escala de frequência dinâmica , por exemplo, SpeedStep para CPUs da Intel). Se você fizer um overclock de uma CPU, geralmente desabilitará esse comportamento, fazendo com que a CPU mantenha a taxa de clock máxima, mesmo quando ociosa.
Nat
2
Consulte também "Estados de energia da ACPI": existem várias maneiras pelas quais um processador pode parar de executar as instruções, mas ainda pode ser ativado.
Pjc50

Respostas:

85

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

O Unix parece sempre ter tido algum tipo de loop ocioso (mas não necessariamente uma tarefa ociosa real, veja a resposta de Gilles ), e mesmo na V1 ele usava uma WAITinstrução que parava o processador até que ocorresse uma interrupção (significava “aguarde interromper"). Alguns outros sistemas operacionais usavam loops ocupados, DOS, OS / 2 e versões anteriores do Windows em particular. Já há muito tempo, as CPUs usam 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, no arch/x86/kernel/process.ckernel Linux: a básica apenas chamaHLT, que interrompe 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 bugs ou ineficiências ( por exemplo, usando em MWAITvez de HLTem algumas CPUs).

Tudo isso é completamente separado dos estados inativos nos processos, quando eles estão aguardando um evento (E / S, etc.).

Stephen Kitt
fonte
3
Heh, eu vejo agora, obrigado. play_dead()é um nome mnemônico muito bom para executar o HALT. Não haveria o risco de enviar HALT para cada CPU e, consequentemente, travar? (ou seja, alcançar essa situação, Halt cada CPU, seria um bug no kernel correto?)
grochmal
30
A CPU acorda do HALT através de uma interrupção.
Johan Myréen
11
@ JohanMyréen - Legal, isso faz sentido. Nesse caso, mesmo uma interrupção de IRQ de um dispositivo de entrada o ativaria novamente. Obrigado.
grochmal
15
Ou de forma mais confiável, a interrupção do timer ... (manipulação Tickless é outra chaleira de peixes.)
Stephen Kitt
3
@EJP, de fato, é uma instrução bastante comum, embora tenha nomes diferentes em arquiteturas diferentes.
user253751
50

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

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

O funcionamento da espera por interrupção depende dos recursos do processador. Com o design mais básico do processador, esse é 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 esteja executando um processador em que não há nada melhor, e a maioria dos processadores tem algo melhor. Em vez de gastar energia sem fazer nada além de aquecer a sala, o ideal é que o processador seja desligado. Portanto, 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 permanece ligada, o controlador de interrupção. Quando um periférico aciona uma interrupção, o controlador de interrupção envia um sinal de ativação para a parte (principal) do processador.

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

Gilles 'SO- parar de ser mau'
fonte
5
Observe que mesmo as CPUs embarcadas mais básicas, como os microcontroladores baseados em AVR, têm uma instrução WFI (Wait For Interrupt), mesmo que essa instrução possa ser equivalente ao NOP, dependendo do modelo exato.
Jonas Schäfer
@JonasWielicki: Eu pensei que você normalmente entraria em um ciclo apertado se não tivesse nada para fazer, ou você poderia entrar em um estado de baixa potência e aguardar a interrupção para derrubá-lo (estados de baixa potência geralmente exigem mais " metal "interrompe).
Nick T
11
As arquiteturas @JonasWielicki projetadas para sistemas embarcados se preocupam com o gerenciamento de energia, para que o WFI seja importante lá. Muitas arquiteturas mais antigas não têm isso. A arquitetura 8086 original não, AFAIR. 68k tem WFI? É um recurso padrão no MIPS? Minha familiaridade com a programação de baixo nível é principalmente no ARM, onde o baixo consumo de energia é uma questão natural e o WFI é apenas a ponta do iceberg de gerenciamento de energia.
Gilles 'SO- stop be evil'
11
@Gilles 8086 teve uma instrução de parada. Consulte en.m.wikipedia.org/wiki/HLT_(x86_instruction). As instruções incluíam a funcionalidade de economia de energia apenas desde o 80486 DX4. Voltando à história, o HLT já estava em 8080 e derivados (como o Z80).
Pabouk
11
O @pabouk HLTpoderia desligar variantes do SL dos 386 e 486, antes da publicação do DX4 (o artigo da Wikipedia está incorreto).
Stephen Kitt
0

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

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

Johan Myréen
fonte
3
Hmmm ... não acho que esse seja o tipo de processo ocioso criado pelo CLONE_IDLETASK. Se não tivesse sido criado, o agendador ignorou os processos inativos do kernel nas CPUs e não precisaria criar nenhum processo para eles durante a inicialização. (DW não é meu embora :))
grochmal
Um pouco googling revela que CLONE_IDLETASK é uma bandeira kernel-interna que foi introduzido em torno do kernel versão 2.5.14 em 2002 e mais tarde removido em 2004.
Johan Myréen
"um" processo inativo, mas não " o " processo inativo.
user253751