Como posso garantir o meu programa de corridas do começo ao fim sem interrupção?

StackOverflow https://stackoverflow.com/questions/1215713

  •  06-07-2019
  •  | 
  •  

Pergunta

Eu estou tentando código de tempo utilizando RDTSC (nenhum outro software profiling eu tentei é capaz de tempo para a necessidade resolução I) no Ubuntu 8.10. No entanto, eu continuo recebendo valores atípicos de interruptores de tarefas e interrupções de queima, que estão causando as minhas estatísticas de ser inválido.

Considerando minhas programa é executado em questão de milissegundos, é possível desativar todas as interrupções (que seria inerentemente desligar interruptores tarefa) no meu ambiente? Ou eu preciso para ir para um sistema operacional que permite me mais poder? Será que eu estaria melhor fora de usar o meu próprio kernel do sistema operacional para executar esse código de tempo? Eu estou tentando provar melhor pior desempenho de um algoritmo / case, por isso deve ser totalmente sólido, com timing.

O código relevante Eu estou usando atualmente é:

inline uint64_t rdtsc()
{
    uint64_t ret;
    asm volatile("rdtsc" : "=A" (ret));
    return ret;
}

void test(int readable_out, uint32_t start, uint32_t end, uint32_t (*fn)(uint32_t, uint32_t))
{
    int i;
    for(i = 0; i <= 100; i++)
    {
        uint64_t clock1 = rdtsc();
        uint32_t ans = fn(start, end);
        uint64_t clock2 = rdtsc();

        uint64_t diff = clock2 - clock1;

        if(readable_out)
            printf("[%3d]\t\t%u [%llu]\n", i, ans, diff);
        else
            printf("%llu\n", diff);
    }
}

Pontos extras para aqueles que notar que eu não estou lidando adequadamente condições de estouro neste Código. Nesta fase eu estou apenas tentando obter uma saída consistente sem saltos repentinos devido ao meu programa de perder a fatia de tempo.

O bom valor para o meu programa é de -20.

Então, para recapitular, é possível para eu executar esse código sem interrupção do sistema operacional? Ou eu estou indo para necessidade de executá-lo em hardware nua em ring0, para que eu possa desativar IRQ e agendamento? Agradecemos antecipadamente!

Foi útil?

Solução

Se você chamar nanosleep () para dormir por um segundo ou assim imediatamente antes de cada iteração do teste, você deve obter uma fatia de tempo "fresco" para cada teste. Se você compilar o kernel com interrupções 100HZ temporizador, e seus concluída função temporizada em menos de 10ms, então você deve ser capaz de evitar interrupções do timer bater-lo dessa maneira.

Para minimizar outras interrupções, desconfigurar todos os dispositivos de rede, configurar o seu sistema sem swap e ter certeza que é outra forma de repouso.

Outras dicas

Tricky. Eu não acho que você pode transformar o sistema operacional 'off' e programação estrita garantia.

Eu transformar esta de cabeça para baixo: uma vez que ele é executado tão rápido, executá-lo muitas vezes para recolher uma distribuição de resultados. Dado que a norma Ubuntu Linux não é um sistema operacional em tempo real no sentido estrito, todos os algoritmos alternativos seria executado na mesma configuração --- e você pode então comparar suas distribuições (usando qualquer coisa de estatísticas de resumo para quantiles para qqplots). Você pode fazer essa comparação com Python, ou R, ou Octave, ... o que melhor lhe convier.

Você pode ser capaz de fugir com o funcionamento FreeDOS , já que é um único processo OS .

Aqui está o texto relevante a partir do segundo link:

implementação DOS da Microsoft, que é o de padrão de facto para sistemas DOS no x86 mundo, é um single-user, -Tasking único sistema operacional. isto fornece acesso raw ao hardware, e apenas uma camada mínima para APIs OS para coisas como o arquivo I / O. Isto é um boa coisa quando se trata de embutidos sistemas, porque muitas vezes você só precisa fazer alguma coisa sem um sistema operacional em seu caminho.

DOS tem (nativamente) o conceito de fios e nenhum conceito de múltiplos, processos em curso. Inscrição software faz chamadas de sistema através do utilização de uma interface de interrupção, chamando várias interrupções de hardware para lidar com coisas como vídeo e áudio, e chamando interrupções de software para lidar com várias coisas como ler um diretório, a execução de um arquivo, e assim por diante.

É claro, você provavelmente vai obter o melhor desempenho realmente arrancar FreeDOS em hardware real, não em um emulador.

Eu não tenho realmente usado FreeDOS, mas presumo que desde que seu programa parece ser padrão C, você vai ser capaz de usar o que o compilador padrão é para FreeDOS.

Se o seu programa é executado em milissegundos, e se você está rodando em Linux, Certifique-se de que a sua frequência de temporizador (no Linux) está definido para 100 Hz (não 1000Hz). (Cd / usr / src / linux; make menuconfig, e olhar para "Tipo de processador e recursos" -> "Temporizador frequência") Desta forma o seu CPU vai ser interrompido a cada 10ms.

Além disso, consideram que o tempo de CPU fatia padrão no Linux é 100ms, assim com um bom nível de -20, você não vai ficar descheduled se você está rodando por alguns milissegundos.

Além disso, você está looping 101 vezes em fn (). Por favor, considere dar fn () para ser um não-op para calibrar o sistema corretamente.

estatísticas Marca (média + desvio-padrão) em vez de imprimir muitas vezes (que iria consumir a sua fatia de tempo programado, e o terminal começará eventualmente cronograma etc ... evitar isso).

código de exemplo RDTSC referência

Você pode usar chrt -f 99 ./test para executar ./test com a prioridade máxima em tempo real. Então, pelo menos, não será interrompido por outros processos do espaço do usuário.

Além disso, a instalação do linux-rt pacote irá instalar um kernel em tempo real, o que lhe dará mais controle sobre prioridade manipulador de interrupção via interrupções de rosca.

Se você executar como root, você pode chamar sched_setscheduler () e dar-se uma prioridade em tempo real. Verifique a documentação.

Talvez haja alguma maneira de escalonamento preemptivo desativar no Linux, mas pode não ser necessário. Você poderia usar informações de /proc/<pid>/schedstat ou algum outro objeto em /proc ao senso quando você foi preterido, e desconsiderar essas amostras de tempo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top