O sistema operacional Linux entende a troca de contexto da CPU por meio do combate real

Prefácio: Linux é um sistema operacional multitarefa que pode suportar tarefas muito maiores que o número de CPUs para rodar ao mesmo tempo, mas todos sabemos que isso é uma ilusão. A verdade é que o sistema aloca CPUs para cada processo por sua vez em um curto período de tempo. Os usuários criam a ilusão de que várias tarefas estão sendo executadas ao mesmo tempo. Então há um problema: antes de cada processo ser executado, a CPU precisa saber de onde o processo é carregado e executado, ou seja, o sistema precisa ajudá-la a definir os registradores da CPU e contadores de programa com antecedência.

1. Contexto da CPU

O contexto da CPU é, na verdade, alguns ambientes que são suportados por esses ambientes, as tarefas podem ser executadas e as condições de hardware desses ambientes são registradores de CPU e contadores de programa. O registrador da CPU é um dispositivo de armazenamento muito pequeno, mas extremamente rápido, embutido na CPU. O contador de programa é necessário para a CPU executar qualquer tarefa. Ele registra informações como o número de linhas da tarefa em execução no momento. Este é o contexto da CPU .

2. Mudança de contexto da CPU

De acordo com diferentes tarefas, a troca de contexto da CPU pode ser dividida em troca de contexto de processo, troca de contexto de thread, troca de contexto de interrupção
e troca de contexto de processo.

No Linux, o Linux divide o espaço de execução do processo em espaço do kernel e espaço do usuário de acordo com o nível de privilégio:

  • O espaço do kernel tem a autoridade mais alta e pode acessar diretamente todos os recursos
  • O espaço do usuário só pode acessar recursos restritos e não pode acessar diretamente dispositivos de hardware, como memória. Para acessar esses recursos privilegiados, você deve usar chamadas de sistema

Para um processo, normalmente ele roda em modo usuário, mas quando precisa acessar dispositivos de hardware como memória e disco, precisa cair em modo kernel, ou seja, precisa mudar de modo usuário para modo kernel, e essa transição requer É implementado por meio de chamadas do sistema. Por exemplo, uma operação para abrir um arquivo precisa chamar open() para abrir o arquivo, read() para ler o conteúdo do arquivo, write() para enviar o conteúdo do arquivo para o console e finalmente close() para fechar o arquivo. Esta é a transferência do sistema

Uma troca de contexto da CPU também ocorre durante a chamada do sistema:

  • A posição original da instrução do modo de usuário no registro da CPU precisa ser salva primeiro e, em seguida, o código do modo kernel é executado
  • O registro da CPU precisa ser atualizado para a posição da instrução do modo kernel e o código do modo kernel é executado

Depois que a chamada do sistema termina, os registradores da CPU precisam restaurar o estado original do usuário salvo e, em seguida, alternar para o espaço do usuário; portanto, no processo de uma chamada do sistema, ocorrerão duas trocas de contexto da CPU, mas geralmente dizemos que a chamada do sistema é uma troca de modo privilegiado em vez de uma troca de contexto, porque não envolve memória virtual e outros recursos do modo de usuário do processo, nem os processos de troca pertencem à troca de contexto dentro do processo. O processo é gerenciado e agendado pelo kernel, e o a troca de processo só pode ocorrer no modo kernel. Portanto, o contexto de um processo inclui recursos no espaço do usuário, como memória virtual, pilha e variáveis ​​globais, bem como o estado do espaço do kernel, como pilhas e registradores do kernel. Portanto, a troca de contexto de um processo é uma etapa a mais do que a chamada do sistema, salvando a memória virtual do processo. Para recursos no espaço do usuário, como memória e pilha, a troca de contexto do processo geralmente leva dezenas de nanossegundos a vários microssegundos de tempo de CPU. Quando o número de troca de contexto do processo é relativamente grande, fará com que a CPU gaste muito tempo em registradores e kernels. A pilha é a preservação e recuperação de recursos como memória virtual. Além disso, o Linux gerencia o relacionamento de mapeamento entre virtual memória e memória física através da tabela rápida TLB. Quando a memória virtual é atualizada, o cache precisa ser atualizado, o que é muito complicado neste sistema de multiprocessamento. , porque vários processadores compartilham um único cache.

A seguir, vamos falar sobre quando será realizada a troca de contexto do processo. Na verdade, o processo precisa mudar de contexto quando for agendado. Pode ser ativo ou passivo.

  • O algoritmo de escalonamento normal do processo do sistema leva à troca de contexto do processo, como o algoritmo de rotação de fatia de tempo usado atualmente.Quando a fatia de tempo de um processo se esgota, a CPU agendará o processo de entrada e alternará para outros processos.
  • Quando os recursos forem insuficientes, o processo será suspenso, por exemplo, quando estiver aguardando IO ou memória insuficiente, ele suspenderá ativamente e aguardará o sistema agendar outros processos.
  • Quando o processo é suspenso ativamente por alguma função sleep sleep(), ele também será reprogramado
  • Quando um processo de alta prioridade estiver em execução, o processo atual também será suspenso
  • Quando ocorre uma interrupção de hardware, o processo na CPU será suspenso pela interrupção

3. Mudança de contexto de thread

Thread é a unidade básica de escalonamento e processo é a unidade básica de propriedade de recursos. Ou seja, o escalonamento de tarefas no kernel é baseado em thread, mas o processo fornece apenas recursos como memória virtual e variáveis ​​globais para o thread . Processo e thread A diferença entre eles não será apresentada aqui
. Então a troca de contexto do thread é realmente dividida em duas situações:

  • Os dois encadeamentos antes e depois pertencem a processos diferentes, porque os recursos não são compartilhados, portanto, a troca de contexto de encadeamento e a troca de contexto de processo neste momento são consistentes
  • As duas threads antes e depois pertencem ao mesmo processo, pois a memória virtual é compartilhada, portanto, ao alternar, recursos como memória virtual permanecem inalterados, apenas dados privados, registros e outros recursos que não são compartilhados pela thread de comutação

Portanto, a troca de threads no mesmo processo consome menos recursos do que a troca de threads em vários processos

 

4. Interrompa a troca de contexto

Interrupção é responder rapidamente a eventos de hardware. Em termos simples, o computador para a coisa atual para lidar com outras coisas e depois retorna para continuar a tarefa anterior. Por exemplo, quando chamamos a função de impressão, a camada inferior da montagem realmente ajudará Nós chamamos uma instrução de int 0x80, que é para chamar o número de interrupção 0x80.
Claro, a interrupção deve primeiro salvar o estado do processo atual, para que o processo ainda possa retomar do estado original após o término da interrupção , e a troca do contexto de interrupção não envolve o processo. Modo usuário, portanto, quando o programa de interrupção interrompe o processo que está no modo usuário, não há necessidade de salvar e restaurar os recursos do modo usuário, como memória virtual e global variáveis ​​deste processo, só precisam salvar e restaurar os recursos no modo kernel do processo, incluindo registradores de CPU, pilhas de kernel,
etc. ao mesmo tempo que a troca de contexto do processo Finalize a execução da tarefa anterior. Quando há muitas trocas de contexto de interrupção, isso consumirá muita
CPU
. O tempo é gasto salvando e restaurando dados como registros, pilhas de kernel e memória virtual, o que reduz o tempo real de execução do processo e se torna um fator no declínio significativo no desempenho do sistema. Portanto, podemos usar a ferramenta vmstat para consultar o status de troca de contexto do sistema. vmstat
é uma ferramenta de análise de desempenho do sistema comumente usada que pode ser usada para analisar o número de trocas e interrupções de contexto da CPU

De particular preocupação são:

  • cs (troca de contexto): o número de trocas de contexto por segundo
  • in(interrupção): o número de interrupções por segundo
  • r (Running ou Runnable): O comprimento da fila de prontos, ou seja, o processo que está rodando e aguardando a CPU
  • b(Bloqueado): o número de processos em um estado de suspensão ininterrupta

Vmstat fornece a situação geral de troca de contexto de todo o sistema. Para visualizar os detalhes de cada processo, você precisa usar o pidstat. Adicione a opção -w para visualizar a situação de troca de contexto do processo

img

De particular preocupação são:

  • cswch(voluntary context switches): Indica o número de trocas de contexto voluntárias por segundo
  • nvcswch(switches de contexto não voluntários): Indica o número de switches de contexto involuntários por segundo

  Informações por meio do trem: rota de aprendizado da tecnologia de código-fonte do kernel do Linux + tutorial em vídeo do código-fonte do kernel

Learning through train: Linux kernel code memory tuning file system process management device driver/network protocol stack

Os respectivos significados desses dois conceitos:

  • Troca voluntária de contexto: quando o processo não consegue obter os recursos necessários, a troca de contexto resultante, como IO, memória e outros recursos insuficientes, ocorrerá troca voluntária de contexto
  • Troca involuntária de contexto: o processo é forçado a ser escalonado pelo sistema porque a fatia de tempo chegou e então ocorre a troca de contexto. Por exemplo, quando um grande número de processos está competindo pela CPU, a troca involuntária de contexto tende a ocorrer

Análise de combate real
O número de trocas de contexto do sistema pode ser verificado preliminarmente por meio das ferramentas acima, mas quando o número de trocas de contexto do sistema é anormal?
O caso usa a ferramenta sysbench para simular a situação de alternância de agendamento multithread. O sysbench é uma ferramenta de benchmarking multithread que pode simular o problema de alternância excessiva de contexto. Primeiro, execute stsbench no primeiro terminal para simular o problema de alternância multithread
#
Com 10 threads Execute um teste de benchmark por 5 minutos para simular o problema de comutação multi-thread sysbench --threads=10 --max-time=300 threads executados
e depois execute vmstat no segundo terminal para verificar a alternância de contexto a cada 1 segundo

Podem ser observados os seguintes indicadores:

  • Coluna R: O comprimento da fila pronta atingiu cerca de 8, que excedeu 2 CPUs, então haverá muita competição de CPU
  • coluna us(usuário) e coluna sy(sistema), o uso da CPU dessas duas colunas atingiu 100% e uma grande quantidade é causada por sy, indicando que a CPU está ocupada principalmente pelo kernel
  • in(interrupção): O valor da coluna in atingiu 10.000, então o processamento da interrupção também é um problema

Em seguida, usamos o pidstat para ver qual processo está com problema. Como o pidstat exibe os dados do indicador do processo por padrão, mas usamos os dados do thread simulados pelo sysbench, precisamos adicionar a opção -t gpw@gopuwe:~$ pidstat -
wt

img

Então, aqui podemos analisar que há muitas trocas de contexto de sub-threads do sysbench. Há
outro problema. Ao usar o vmstat, descobrimos que há mais dados no indicador in, então precisamos descobrir que tipo de interrupção causou a interrupção. Up, a interrupção deve ter ocorrido no modo kernel, mas pidstat é apenas uma ferramenta de análise de desempenho do processo e não fornece nenhuma informação detalhada sobre a interrupção. Podemos lê-la no arquivo somente leitura /proc
/ interrupções, /proc é um arquivo virtual O sistema é usado para comunicação entre o espaço do kernel e o espaço do usuário. /proc/interrupts fornece um uso de interrupção somente leitura. Você pode usar o comando cat para visualizar /proc/interrupts e descobrir que a mudança mais rápida é a interrupção de reagendamento RES , esse tipo de interrupção significa acordar a CPU no estado ocioso para agendar novas tarefas a serem executadas e também é chamada de interrupção do processador Então, quantas vezes é o número apropriado
de trocas de contexto?
Este valor realmente depende do desempenho da CPU do próprio sistema.Na minha opinião, se o número de trocas de contexto no sistema é relativamente estável
, deve ser considerado normal se o número de trocas de contexto varia de centenas a menos de 10.000. No entanto, quando o número de trocas de contexto ultrapassa 10.000, ou
o número de trocas aumenta em uma ordem de grandeza, é provável que tenham ocorrido problemas de desempenho. Nesse momento, análises específicas devem ser feitas de acordo com o tipo de troca de contexto, por exemplo :

  • Existem mais trocas de contexto voluntárias, indicando que os processos estão aguardando recursos e outros problemas, como E/S, podem ter ocorrido;
  • Existem mais trocas de contexto involuntárias, o que significa que os processos estão sendo agendados à força, ou seja, todos estão competindo pela CPU, o que significa que a CPU realmente se tornou um gargalo;
  • O número de interrupções aumentou, indicando que a CPU está ocupada pelo manipulador de interrupções e você precisa verificar o arquivo /proc/interrupts

 

Acho que você gosta

Origin blog.csdn.net/youzhangjing_/article/details/131436171
Recomendado
Clasificación