Como você pode garantir que seu código seja executado sem variabilidade no tempo de execução devido ao cache?

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

Pergunta

Em uma aplicação embarcada (escrita em C, em um processador de 32 bits) com restrições rígidas de tempo real, o tempo de execução de código crítico (especialmente interrupções) precisa ser constante.

Como você garante que a variabilidade do tempo não seja introduzida na execução do código, especificamente devido aos caches do processador (seja L1, L2 ou L3)?

Observe que estamos preocupados com o comportamento do cache devido ao enorme efeito que tem na velocidade de execução (às vezes mais de 100:1 vs.acessando RAM).A variabilidade introduzida devido à arquitetura específica do processador não chega nem perto da magnitude do cache.

Foi útil?

Solução

Se você conseguir colocar as mãos no hardware ou trabalhar com alguém que possa, poderá desligar o cache.Algumas CPUs possuem um pino que, se conectado ao terra em vez da alimentação (ou talvez ao contrário), desativará todos os caches internos.Isso dará previsibilidade, mas não velocidade!

Caso contrário, talvez em certos lugares do código do software possa ser escrito para preencher deliberadamente o cache com lixo, então o que quer que aconteça a seguir pode ser garantido como uma falha no cache.Feito da maneira certa, isso pode dar previsibilidade e talvez só possa ser feito em determinados lugares, de modo que a velocidade pode ser melhor do que desabilitar totalmente os caches.

Finalmente, se a velocidade importa - projete cuidadosamente o software e os dados como se fosse nos velhos tempos da programação para uma CPU antiga de 8 bits - mantenha-o pequeno o suficiente para que tudo caiba no cache L1.Sempre fico surpreso ao ver como os caches integrados hoje em dia são maiores do que toda a RAM de um minicomputador da década anterior.Mas isso será um trabalho árduo e exigirá inteligência.Boa sorte!

Outras dicas

Duas possibilidades:

Desative totalmente o cache.O aplicativo será executado mais lentamente, mas sem qualquer variabilidade.

Pré-carregue o código no cache e "bloqueie-o".A maioria dos processadores fornece um mecanismo para fazer isso.

Parece que você está se referindo à família de processadores x86 que não é construída com sistemas em tempo real em mente, portanto não há garantia real de execução em tempo constante (a CPU pode reordenar microinstruções, do que há previsão de ramificação e fila de pré-busca de instruções que é liberado toda vez que a CPU prevê erroneamente saltos condicionais...)

Esta resposta pode parecer sarcástica, mas pretende fazer você pensar:

Execute o código apenas uma vez.

A razão pela qual digo isso é porque muitas coisas tornarão isso variável e você pode nem ter controle sobre isso.E qual é a sua definição de tempo?Suponha que o sistema operacional decida colocar seu processo na fila de espera.

Em seguida, você tem imprevisibilidade devido ao desempenho do cache, latência de memória, E/S de disco e assim por diante.Tudo isso se resume a uma coisa;às vezes leva tempo para colocar as informações no processador onde seu código pode usá-las.Incluindo o tempo que leva para buscar/decodificar seu próprio código.

Além disso, quanta variação é aceitável para você?Pode ser que você esteja bem com 40 milissegundos ou com 10 nanossegundos.

Dependendo do domínio do aplicativo, você pode ainda mais mascarar ou ocultar a variação.O pessoal de computação gráfica tem renderizado em buffers fora da tela há anos para ocultar a variação no tempo de renderização de cada quadro.

As soluções tradicionais apenas removem o máximo possível de taxas variáveis ​​conhecidas.Carregue arquivos na RAM, aqueça o cache e evite IO.

Se você fizer todas as chamadas de função no código crítico 'inline' e minimizar o número de variáveis ​​​​que você possui, para que você possa deixá-las ter o tipo 'registro'.Isso deve melhorar o tempo de execução do seu programa.(Você provavelmente terá que compilá-lo de uma maneira especial, já que os compiladores hoje em dia tendem a desconsiderar suas tags de 'registro')

Presumo que você tenha memória suficiente para não causar falhas de página ao tentar carregar algo da memória.As falhas de página podem levar muito tempo.

Você também pode dar uma olhada no código assembly gerado para ver se há muitas ramificações e instruções de memória que podem alterar seu código em execução.

Se ocorrer uma interrupção na execução do seu código, isso levará mais tempo.Você tem interrupções/exceções habilitadas?

Pré-aloque memória e certifique-se de que as interrupções não afetem o cache (impossível, certo).

/Allan

Entenda o pior cenário de tempo de execução para operações complexas e use temporizadores.

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