Fiquei me perguntando o que as pessoas abordam ou pensam sobre como automatizar o teste de desempenho no XNA. Atualmente, estou olhando apenas para trabalhar em 2D, mas isso representa muitas áreas em que o desempenho pode ser aprimorado com diferentes implementações.
Um exemplo seria se você tivesse duas implementações diferentes de particionamento espacial, uma pode ser mais rápida que a outra, mas sem fazer alguns testes de desempenho reais, você não seria capaz de dizer qual deles com certeza (a menos que visse que o código estava descaradamente lento em certos peças). Você pode escrever um teste de unidade que, por um determinado período, continue adicionando / atualizando / removendo entidades para ambas as implementações e veja quantas foram feitas em cada período de tempo e quanto maior, mais rápido será o mais rápido (neste exemplo).
Outro exemplo de nível superior seria se você quisesse ver quantas entidades você pode ter na tela aproximadamente sem ficar abaixo de 60fps. O problema disso é que, para automatizá-lo, você precisará usar o truque de forma oculta ou alguma outra coisa para iniciar um jogo falso e testar puramente quais partes são importantes e desativar todo o resto.
Sei que esse não é um caso simples, realmente, mesmo que você possa automatizar os testes; realmente depende de um ser humano interpretar se os resultados têm desempenho suficiente, mas, como parte de uma etapa de construção, você pode executar esses testes e publicar os resultados em algum lugar para comparação.
Dessa forma, se você for da versão 1.1 para 1.2, mas alterou alguns algoritmos subjacentes, poderá perceber que geralmente a pontuação de desempenho teria aumentado, o que significa que você melhorou o desempenho geral do aplicativo e, em seguida, de 1.2 para 1.3, pode perceber que você diminuiu um pouco o desempenho geral.
Então, alguém automatizou esse tipo de coisa em seus projetos? Em caso afirmativo, como você mede suas comparações de desempenho em alto nível e quais estruturas você usa para testar? Ao fornecer o código que você escreveu para que seja testável / ridicularizado na maioria das partes, você pode apenas usar seus testes como um mecanismo para obter alguns resultados de desempenho ...
=== Editar ===
Apenas para maior clareza, estou mais interessado na melhor maneira de usar testes automatizados no XNA para rastrear seu desempenho, não para testar ou adivinhar executando manualmente o jogo em uma máquina. Isso é completamente diferente de ver se o seu jogo pode ser jogado no hardware X, é mais sobre acompanhar a mudança no desempenho à medida que o mecanismo / estrutura do jogo muda.
Conforme mencionado em um dos comentários, você pode testar facilmente "quantos nós posso inserir / remover / atualizar dentro do QuadTreeA em 2 segundos", mas você deve examinar fisicamente esses resultados sempre para ver se foram alterados, o que pode ser bem e ainda é melhor do que apenas jogar, para ver se você percebe alguma diferença entre as versões. No entanto, se você colocar uma declaração para notificá-lo de uma falha, se ela for menor do que, digamos, 5000 em 2 segundos, você terá um teste quebradiço, pois é contextual ao hardware, não apenas à implementação. Embora isso seja dito, esse tipo de teste automatizado é realmente útil se você estiver executando seus testes como algum tipo de pipeline de criação, ou seja:
Caixa -> Executar testes de unidade -> Executar testes de integração -> Executar testes de desempenho -> Pacote
Portanto, você pode comparar facilmente as estatísticas de uma construção para outra no servidor de IC como um relatório de algum tipo e, novamente, isso pode não significar muito para ninguém, se você não estiver acostumado à Integração Contínua. O principal ponto crucial dessa questão é ver como as pessoas gerenciam isso entre compilações e como elas acham melhor informar sobre elas. Como eu disse, pode ser subjetivo, mas como o conhecimento será obtido com as respostas, parece uma pergunta que vale a pena.
fonte
Respostas:
Suponho que você queira descartar completamente "Executar o jogo real", então basicamente minha resposta é desqualificada desde o início. Mas talvez você possa tirar algo disso, por isso eu posto isso independentemente:
Para minha tese de mestrado, tenho várias implementações independentes / paralelas para obter o mesmo em alguns módulos do mecanismo de jogo e preciso realizar algumas medições de desempenho. Tecnicamente, nada me impediria de executar o jogo e olhar para os números exibidos no criador de perfil na tela, mas eu ainda queria automatizar isso porque é um processo tedioso de executar sempre que minha implementação é alterada.
Então, o que eu tenho é o seguinte:
Então, o que isso me permite fazer é iniciar meu aplicativo a partir de qualquer ambiente de script meio decente (por exemplo, prompt de comando do Windows por meio de scripts em lote - mas na verdade eu uso o Ruby para esse fim), definir um caminho de arquivo de despejo, carregar um mapa e deixá-lo executando por alguns minutos, encerre o jogo em execução, defina outro caminho do arquivo de despejo, mude o algoritmo para usar, carregue o mapa novamente, enxágue, repita. O script Ruby se comunica com o jogo em andamento, criando esse arquivo especial que o módulo de linha de comando está procurando e colocando os comandos desejados na sintaxe que a linha de comando entende nele.
Na verdade, não tenho integração contínua neste projeto no momento, mas nada me impediria de aprimorar esse script Ruby para também analisar os logs de desempenho gerados e produzir XML compatível com xUnit para se comunicar com o sistema de CI quando o desempenho tiver inesperadamente por algum motivo e execute o script em todas as compilações completas no servidor de compilação.
Tudo bem, então meu jogo também não é escrito em XNA (é simples em C ++ e DirectX), nem essa abordagem respeita o fato de que você realmente não deseja executar o jogo em seu servidor de build. Ele também não é nem de longe tão flexível quanto o que você provavelmente deseja - mas, ainda assim, é uma abordagem simples e de baixa tecnologia para a medição automatizada de desempenho que é um pouco favorável ao CI (desde que um servidor de construção robusto seja).
Edit: Quanto ao quão longe eu realmente levei essa abordagem - só comparo as medições de desempenho obtidas em diferentes implementações deste módulo. Mas todo o sistema é configurado de uma maneira que me permita despejar qualquer uma das categorias definidas para minha estrutura de criação de perfil leve e usar o ambiente de script externo para interpretar os resultados da maneira que parecer útil aqui e ali. Tirando o aspecto do perfil de desempenho da equação, pretendo ainda
fonte
Não vejo o que você descreve como uma ferramenta útil. Como desenvolvedor, um número simples de desempenho é quase inútil.
O que você deseja é criar um perfil do seu código, dividi-lo em partes lógicas e medir quanto tempo cada um deles usa, pico e média. Agora você pode dizer qual parte do código está causando problemas e sabe onde procurar otimizações.
A parte complicada não são as alterações de desempenho de uma construção para a outra, você não precisa de um automatizado para descobrir isso. A parte complicada são as diferenças de desempenho entre máquinas diferentes, não há como extrapolar o desempenho de uma máquina para outra com uma placa de vídeo diferente etc.
Então, o que você quer é um recurso de referência para que você possa executar um clique e obter os números de criação de perfil. Dessa forma, você poderá testar várias máquinas simultaneamente. Existem várias maneiras de fazer isso, por exemplo, você pode substituir a entrada do usuário para chegar o mais próximo possível da execução de uma sessão normal do jogo.
Você também pode querer fazer um teste mais longo para detectar vazamentos de memória.
fonte