Estou escrevendo um aplicativo em tempo real suave em c #. Certas tarefas, como responder a solicitações de hardware provenientes de uma rede, precisam ser concluídas dentro de uma certa quantidade de milissegundos; no entanto, não é 100% de missão crítica fazer isso (ou seja, podemos tolerar que seja pontual na maior parte do tempo, e o 1% é indesejável, mas não uma falha), daí a parte "flexível".
Agora percebo que o C # é uma linguagem gerenciada, e as linguagens gerenciadas não são particularmente adequadas para aplicativos em tempo real. No entanto, a velocidade na qual podemos realizar as tarefas em C #, bem como os recursos da linguagem, como gerenciamento de reflexão e memória, facilitam muito a tarefa de criar esse aplicativo.
Existem otimizações ou estratégias de design que podemos adotar para reduzir a quantidade de sobrecarga e aumentar o determinismo? Idealmente, eu teria os seguintes objetivos
- Atrasar a coleta de lixo até que ela seja "segura"
- Permitir que o coletor de lixo funcione sem interferir nos processos em tempo real
- Prioridades de thread / processo para diferentes tarefas
Existem maneiras de fazer isso em C # e outras coisas a serem observadas em tempo real ao usar o C #?
O destino da plataforma para o aplicativo é o .NET 4.0 Client Profile no Windows 7 de 64 bits, com. Eu o configurei atualmente para o perfil do cliente, mas essa era apenas a opção padrão e não foi escolhida por nenhum motivo específico.
fonte
Respostas:
A otimização que atende aos seus dois primeiros marcadores é chamada de pool de objetos . Funciona por
Você pode encontrar um exemplo de classe que implementa um pool de objetos usando um
ConcurrentBag
aqui .A prioridade do thread / processo pode ser facilmente configurada em tempo de execução. A classe Thread possui métodos e propriedades que permitem definir a prioridade e a afinidade do processador. A classe de processo contém recursos semelhantes.
fonte
Você pode fazer isso definindo o modo de latência do GC como
LowLatency
. Para mais informações, consulte esta resposta no SO .fonte
Adote a mesma abordagem que o desenvolvimento de jogos faz em um ambiente gerenciado e tente minimizar a criação / morte de objetos até o mínimo absoluto.
Por exemplo, tente criar todos os objetos que provavelmente serão necessários no início e agrupe obsessivamente, passe por ref sempre que possível, evite operações que criem objetos intermediários de curto prazo
fonte
Lembre-se de que o ambiente de destino (Windows) é um O / S multitarefa preventivo. Em outras palavras, seu processo em tempo real será inevitavelmente antecipado em algum momento ou outro, o que introduzirá outras latências além da coleta de lixo do .NET. Você pode atenuá-lo, reduzindo o valor da fatia de tempo (quantum) (o padrão é algo como 16ms) e elevando a prioridade do seu processo (mas existem limites práticos), mas as pré-emptions / ainda devem ocorrer porque outros processos essenciais ainda precisam fazer coisas. Tudo isso não tem nada a ver com linguagem de programação; é fundamental para o sistema operacional.
Problemas de GC à parte, seu aplicativo em execução em uma máquina Windows pronta para o uso provavelmente será capaz de fornecer latências de alguns milissegundos na maior parte do tempo. Certamente não pode ser garantido 100% do tempo, ou algo próximo. Mesmo com o ajuste (quantum curto, alta prioridade), você ainda obtém altas latências ocasionais. É a natureza da besta.
Conclusão: se você precisar de tempos de resposta garantidos, especialmente na ordem de alguns milissegundos, o Windows provavelmente não é a melhor opção para o sistema operacional de entrega.
fonte