3 pontos por GN⁺ 2024-10-20 | 1 comentários | Compartilhar no WhatsApp
  • O escalonador de CPU do kernel oferece vários modos de preempção que implementam um compromisso entre vazão do sistema e tempo de resposta.
  • Em setembro de 2023, durante discussões sobre escalonamento, foi proposto o conceito de "preempção preguiçosa (lazy preemption)", que pode simplificar o escalonamento do kernel ao mesmo tempo em que oferece resultados melhores.
  • A ideia ficou em silêncio por algum tempo, mas reapareceu com uma série de patches de Peter Zijlstra.

Modos atuais de preempção no kernel

  • PREEMPT_NONE: a preempção só é permitida quando a tarefa em execução esgota seu time slice.
  • PREEMPT_VOLUNTARY: adiciona muitos pontos no kernel onde a preempção é possível quando necessário.
  • PREEMPT_FULL: permite preempção em quase todos os pontos, exceto quando há spinlocks mantidos.
  • PREEMPT_RT: prioriza a preempção acima da maioria das outras coisas, tornando preemptível também a maior parte do código com spinlocks.

Introdução da preempção preguiçosa

  • O patch de preempção preguiçosa adiciona uma nova flag TIF_NEED_RESCHED_LAZY para indicar que um reescalonamento será necessário em algum momento, e não imediatamente.
  • No modo de preempção preguiçosa (PREEMPT_LAZY), a maioria dos eventos define essa nova flag, e ao retornar do kernel para o espaço do usuário, a chamada ao escalonador ocorre se qualquer uma das duas flags estiver definida.
  • Como resultado dessa mudança, no modo de preempção preguiçosa a maioria dos eventos no kernel deixa de preemptar a tarefa atual.

Remoção de cond_resched()

  • O objetivo final desse trabalho é deixar apenas dois modos não em tempo real: PREEMPT_LAZY e PREEMPT_FULL.
  • O modo preguiçoso ocupa a posição entre PREEMPT_NONE e PREEMPT_VOLUNTARY, substituindo esses dois modos.
  • Atualmente, ainda restam chamadas a cond_resched(), e elas são necessárias enquanto os modos PREEMPT_NONE e PREEMPT_VOLUNTARY existirem.

Resumo do GN⁺

  • A preempção preguiçosa pode ajudar a simplificar o escalonamento do kernel e a oferecer latências mais previsíveis.
  • Esse trabalho pode ajudar a reduzir o tamanho do kernel e simplificar o código.
  • A preempção preguiçosa oferece vazão semelhante à do PREEMPT_VOLUNTARY, mas ainda precisa de mais testes e otimização.
  • Um outro projeto com funcionalidade semelhante é o escalonador ULE do FreeBSD.

1 comentários

 
GN⁺ 2024-10-20
Comentários no Hacker News
  • O resultado final do trabalho de preempção preguiçosa é que o kernel fique menor e mais simples, ao mesmo tempo em que oferece latência previsível. Isso parece ser uma solução melhor, sem a necessidade de espalhar chamadas relacionadas ao escalonador por todo o código. No entanto, levará tempo para alcançar isso.

    • Assim como o EEVDF, isso simplifica e melhora o estado atual. Provavelmente não haverá solução melhor.
  • Um nível alto de preempção permite que o sistema reaja mais rapidamente a eventos. Reações rápidas a eventos como o movimento do mouse ou um sinal de "colapso iminente" de um reator são mais satisfatórias. No entanto, um nível alto de preempção pode afetar a taxa de transferência total do sistema. Cargas de trabalho com muitas tarefas intensivas em CPU se beneficiam de sofrer o mínimo possível de interrupções. Preempções mais frequentes podem causar maior contenção de locks. É por isso que existem modos diferentes, e o modo ideal de preempção provavelmente depende da carga de trabalho.

    • Fico me perguntando por que o nível de preempção é uma propriedade de um modo global, e não uma propriedade de um evento específico. Alguns eventos deveriam ser tratados com latência menor do que outros.
  • O kernel atual tem quatro modos que controlam quando uma tarefa pode ser preemptada em favor de outra.

    • Fico me perguntando se isso diz respeito a tarefas do kernel, tarefas de usuário ou ambas.
  • Não consegui encontrar números relacionados ao patch no tópico linkado. Algum benchmark preliminar deve ter sido feito para indicar o potencial real da mudança.

  • Fico me perguntando o quão fortemente acoplado o escalonador está ao restante do código do kernel.

    • Por exemplo, ao querer simplificar drasticamente o escalonador para aplicações científicas que não se importam nem um pouco com preempção, será que isso poderia ser feito de forma limpa e modular, e quais seriam os benefícios?
  • Seria bom se a preempção pudesse se adaptar de acordo com o evento, mas gerenciar isso para todos os eventos pode prejudicar a estabilidade do sistema. Isso é parecido com gerar leads usando ferramentas como o Tomba Finder.

    • É preciso equilibrar precisão (leads-alvo) e eficiência para que tudo funcione de forma fluida no geral.