Como a preempção funciona no Linux quando um programa tem um temporizador menor que 4ms?

6

Jiffies na maioria dos sistemas Linux são padronizados para 250 (4ms). A questão é que o que acontece quando um programa tem um usleep () menor que 4ms? Claro que funciona como deveria quando está agendado. Mas o que acontece quando o linux scheduler pega este programa para esperar, porque outro programa tem que operar? Como funciona a preempção neste caso?

Devo evitar programas personalizados com uma espera tão pequena? Eles não poderiam ser precisos, poderia?

    
por roncsak 09.11.2012 / 10:17

2 respostas

6

Veja o horário (7) e as páginas de trabalho que ele referencia. Um trecho:

High-Resolution Timers
   Before Linux 2.6.21, the accuracy of timer and sleep system calls  (see
   below) was also limited by the size of the jiffy.

   Since  Linux  2.6.21,  Linux  supports  high-resolution  timers (HRTs),
   optionally configurable via CONFIG_HIGH_RES_TIMERS.  On a  system  that
   supports  HRTs,  the  accuracy  of  sleep  and timer system calls is no
   longer constrained by the jiffy, but instead can be as accurate as  the
   hardware  allows  (microsecond accuracy is typical of modern hardware).
   You can determine  whether  high-resolution  timers  are  supported  by
   checking  the resolution returned by a call to clock_getres(2) or look‐
   ing at the "resolution" entries in /proc/timer_list.

   HRTs are not supported on all hardware architectures.  (Support is pro‐
   vided on x86, arm, and powerpc, among others.)

Um comentário sugere que você não pode dormir menos que um instante. Isso está incorreto; com os HRTs, você pode. Experimente este programa:

/* test_hrt.c */
#include <time.h>
main()
{
        struct timespec ts;
        int i;

        ts.tv_sec = 0;
        ts.tv_nsec = 500000;  /* 0.5 milliseconds */
        for (i = 0; i < 1000; i++) {
                clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
        }
}

Compile:

$ gcc -o test_hrt test_hrt.c -lrt

Execute:

$ time ./test_hrt

real    0m0.598s
user    0m0.008s
sys     0m0.016s

Como você pode ver, 1000 iterações de um atraso de 0,5 milissegundos levaram apenas um pouco mais de 0,5 segundos, como esperado. Se clock_nanosleep estivesse realmente esperando até o próximo instante antes de retornar, levaria pelo menos 4 segundos.

Agora, a pergunta original era: o que acontece se seu programa foi agendado durante esse período? E a resposta é que isso depende da prioridade. Mesmo que outro programa seja agendado enquanto o programa estiver em execução, se o programa tiver maior prioridade ou o agendador decidir que é o tempo de execução do seu programa, ele será executado novamente após o retorno do tempo limite de clock_nanosleep . Não precisa esperar até o próximo instante para que isso aconteça. Você pode tentar executar o programa de teste acima enquanto executa outro software que usa a CPU, e verá que ele ainda é executado na mesma quantidade de tempo, especialmente se você aumentar a prioridade com, por exemplo.

$ time sudo schedtool -R -p 99 -e ./test_hrt
    
por 09.11.2012 / 20:26
4

A menos que você esteja executando um kernel em tempo real, eu não usaria horas de sono < 10ms de qualquer maneira tbh. Mesmo que o agendador esteja disposto a antecipar outro processo para o seu tempo limite, o jitter provavelmente dominará seus tempos de sono reais.

Resumo: evite intervalos tão pequenos, a menos que você tenha um kernel em tempo real. Se você não pode mudar o kernel, sua melhor aposta pode ser fixar o seu processo em uma CPU dedicada com SCHED_FIFO e esperar ocupado (ou fazer outro trabalho útil) por algo menor que cerca de dois momentos.

De alguma forma, o resumo acabou sendo mais longo que o original ... ah, bem.

    
por 09.11.2012 / 12:36