Micro-otimização - BAD vs desenvolvimento de jogos

12

No desenvolvimento de jogos, há muito C / C ++, nos aplicativos de negócios C #. Eu já vi desenvolvedores de C / C ++ expressarem preocupação sobre como uma única linha de código se traduz em assembly. No .NET, alguns vão para IL, raramente.

Em C #, a "otimização micro" é desaprovada, rara e geralmente uma perda de tempo. Este não parece ser o caso no desenvolvimento de jogos.

O que especificamente cria essa inconsistência? Os jogos constantemente aumentam os limites do hardware? Em caso afirmativo, à medida que o hardware melhora, devemos esperar que idiomas de nível superior assumam o controle da indústria de jogos?

Não estou procurando um debate sobre a viabilidade do C # como um desenvolvedor de jogos. Eu sei que isso já foi feito até certo ponto. Foco na micro-otimização. Especificamente, a diferença entre o desenvolvedor de jogos e o desenvolvedor de aplicativos.

ATUALIZAÇÃO
Por jogo, quero dizer desenvolvimento moderno e em larga escala. Por exemplo, MMORPGs, Xbox, PS3, Wii ...

P.Brian.Mackey
fonte
3
Eu trabalhei como desenvolvedor de jogos e desenvolvedor de aplicativos e as diferenças são discutíveis. A micro otimização sem criação de perfil é desaprovada em ambos. Muitos jogos não têm requisitos muito poderosos e não exigem nenhuma otimização. Alguns aplicativos de negócios exigem requisitos muito mais rigorosos (por exemplo, tempo de atividade e garantias em tempo real) do que um jogo médio de 60Hz.
precisa
1
Um fator extra é que, em aplicativos de negócios, você geralmente pode escolher o hardware (dentro do razoável). Se precisar de mais poder de processamento, posso comprar outro servidor ou pagar mais tempo na AWS. Nos jogos, exigir o hardware mais recente transforma um jogo de US $ 60 em um jogo e uma placa de vídeo de US $ 1.060. Se você estiver desenvolvendo para consoles, atualizar o hardware pode significar um atraso por anos, aguardando a próxima geração. Quando você não pode obter um hardware melhor, precisa usá-lo melhor.
Andrew
1
relacionados: wiki.c2.com/?PrematureOptimization
Peter

Respostas:

17

Nos aplicativos de negócios, a CPU nem sempre é o gargalo. Um aplicativo de negócios passaria a maior parte do tempo esperando. Por exemplo:

  1. aguardando resultados da consulta ao banco de dados
  2. aguardando a conclusão da solicitação da Web
  3. aguardando que o usuário faça uma ação da interface do usuário

É por isso que o código que otimiza o desempenho do processamento não agrega muito valor.

A principal consideração é:

  1. Tempo para o mercado
  2. Simplicidade, alguém pode entender e manter o código
Shamit Verma
fonte
6
Eu apontaria que o código que otimiza as consultas ao banco de dados pode melhorar muito a usabilidade dos aplicativos de negócios.
HLGEM 31/03
4
+1. A otimização do banco de dados e da rede geralmente daria mais retorno financeiro em aplicativos de negócios. Escolha por exemplo de JSON vs índices XML e ajuste DB
Shamit Verma
2
+1, mas você deve adicionar o outro lado da equação: o "loop principal (s)" e a renderização (s) nos jogos nos quais a fluidez do jogo depende, faz com que cada microssegundo perca uma perda de valor, porque a qualidade é perceptível para os olhos e outros sentidos.
Klaim
1
Bem dito. E, de fato, tendo feito aplicativos de negócios e desenvolvimento de jogos, passei um tempo examinando uma consulta SQL complexa tentando obter mais desempenho, da mesma forma que passei um tempo examinando um loop interno de um jogo.
Carson63000
Tudo volta à otimização prematura é a raiz de todo mal . A criação de perfil revela claramente que a maior parte do tempo gasto em seu aplicativo comercial médio é de IO de rede + banco de dados.
Alex Reinking
13

Nos aplicativos de negócios, é muito raro que os microssegundos sejam importantes. Nos jogos, é um fato da vida.

Se você deseja ter um jogo rodando a 60 quadros por segundo, você tem ~ 16,67 milissegundos para fazer tudo o que precisa ser feito para esse quadro - entrada, física, lógica de jogo, áudio, rede, IA, renderização e assim por diante; se tiver sorte, você rodará a 30 qps e terá 33,3 milissegundos de luxo. Se um quadro demorar muito, suas críticas serão prejudicadas, seus jogadores preencherão os fóruns da Internet com bile e você não venderá tanto quanto pode (para não mencionar o golpe no seu orgulho profissional) e, se tiver realmente azar, você encontrará sua equipe codificando aplicativos de negócios para ganhar a vida.

Obviamente, os desenvolvedores de jogos não se preocupam com todas as linhas, pois, com a experiência e um perfil decentes, você aprende com as quais as linhas precisam se preocupar. Por outro lado, essas preocupações às vezes afetam coisas que no mundo dos negócios provavelmente seriam consideradas nano-otimizações em vez de micro-otimizações.

Não espere que nenhuma linguagem de alto nível expanda o C ++ até que um ofereça desempenho comparável e previsível.

molbdnilo
fonte
8
Em aplicativos de negociação de alta frequência, microssegundos são muito importantes!
Quant_dev 11/05/11
2
@quant: Como na maioria dos aplicativos de processamento de fluxo - robótica, redes de energia, foguetes, tecnologia médica, etc. Crie muito de um backlog e pode ser tarde demais quando você o atualizar.
Aaronaught
@quant_dev: aplicativos de negociação de alta frequência são muito raros.
Molbdnilo 12/05
Não mais. Eles são mais raros do que os aplicativos de contabilidade, mas são mais comuns do que, digamos, os softwares de design de aviões.
Quant_dev 12/05/11
Os microssegundos também são importantes nos aplicativos de negócios; o gargalo geralmente é encontrado em outro lugar (na rede, em um banco de dados ou sistema de arquivos).
precisa saber é o seguinte
9

Ok, então você viu desenvolvedores de C e C ++ obcecados por linhas individuais. Aposto que eles não ficam obcecados com cada linha.

Há casos em que você deseja o desempenho máximo, e isso inclui muitos jogos. Os jogos sempre tentaram forçar os limites de desempenho, a fim de parecerem melhores do que seus concorrentes no mesmo hardware. Isso significa que você aplica todas as técnicas usuais de otimização. Comece com algoritmos e estruturas de dados e mude para lá. Ao usar um criador de perfil, é possível descobrir onde está demorando mais tempo e onde é possível obter ganhos significativos ao otimizar algumas linhas.

Isso não ocorre porque os idiomas forçam as pessoas a isso, é que as pessoas escolhem idiomas com base no que desejam fazer. Se você deseja extrair o último desempenho de um programa, não escreve C # e compila no CLR e espera que o compilador JIT (ou o que seja) faça um bom trabalho, escreva-o em algo em que possa controlar amplamente a saída. Você usará C ou C ++ (e provavelmente um subconjunto restrito de C ++) e estudará a saída da linguagem assembly e os resultados do criador de perfil.

Muitas pessoas usam C e C ++ e não se preocupam muito com os detalhes da tradução, desde que pareça rápido o suficiente.

David Thornley
fonte
7

Os jogos constantemente aumentam os limites do hardware?

Sim, eles fazem.

Em caso afirmativo, à medida que o hardware melhora, devemos esperar que idiomas de nível superior assumam o controle da indústria de jogos?

Na verdade, não - porque à medida que o hardware melhora, os consumidores esperam que os jogos também melhorem. Eles não esperam que a mesma qualidade do jogo seja desenvolvida com mais eficiência, porque os desenvolvedores usaram uma linguagem de nível superior. Eles esperam ter suas meias arrancadas a cada nova plataforma.

Claro, há algum movimento. Quando eu era garoto e me interessei primeiro pelo desenvolvimento de jogos, era uma montagem manuscrita ou foi embora. Esta foi a era Commodore 64. Atualmente, é claro, o C ++ é a língua franca da maioria dos desenvolvimentos de jogos. E, de fato, vimos um movimento no sentido de usar C ++ para código de mecanismo e uma linguagem de script de nível superior para código de lógica de jogo. por exemplo, LUA, ou o mecanismo Unreal possui sua própria linguagem UnrealScript.

Carson63000
fonte
1
Hoje em dia, uma boa parte dos desenvolvedores de jogos usa uma camada de mecanismo hiper otimizada, escrita por outra pessoa, depois usa algo como Python, ou C ++ menos meticuloso, para agrupar as coisas.
Morgan Herlocker
Relevante observar que o Unreal agora mudou seus scripts "para trás", de UnrealScript para C ++. O melhor do C ++ moderno é que ele permite escrever códigos de baixa latência micro otimizados e lógica concisa de alto nível. A maioria dos outros idiomas alcança alto nível sacrificando a latência e, geralmente, também o desempenho.
leftaroundabout
7

Em C #, a "otimização micro" é desaprovada, rara e geralmente uma perda de tempo. Este não parece ser o caso no desenvolvimento de jogos.

Se você pode simplesmente montar seu aplicativo com código de alto nível e código de biblioteca, é uma perda de tempo. Escreva-o em um idioma interpretado, se desejar; não fará muita diferença. Se você está tentando implementar um mecanismo de iluminação global de ponta que voxeliza o conteúdo dinâmico da cena em tempo real, como o CryEngine 3 , não há como evitar a otimização micro.


fonte
0

"Jogo" é um termo bastante abrangente. Se você tivesse, digamos, um MMORPG, otimizações menores afetariam muitos jogadores.

Os jogadores são, e provavelmente sempre foram, acostumados a uma quantidade comparativamente grande de coisas acontecendo ao mesmo tempo, em tempo real. Certo; ao mesmo tempo, ter um Pacman ou Tetris responsivo era o objetivo. Mas eles ainda tinham que ser responsivos. Atualmente, o 3DMMORPGs via conexões de rede que descartam pacotes.

Eu com certeza entendo o desejo de otimizar.

Jonta
fonte
0

Os jogos constantemente fazem grandes quantidades de processamento em segundo plano. Aplicativos de negócios não.

user16764
fonte
4
Não faça muitos aplicativos de negócios, não é?
APENAS MINHA OPINIÃO correta
2
O suficiente para saber que os aplicativos de negócios não precisam atualizar seu status 60 vezes por segundo. Além disso, eu disse especificamente "constantemente".
User16764 12/12/11
2
Já ouviu falar de negociações em tempo real?
APENAS MINHA OPINIÃO correta
0

Eu sempre achei o termo "micro-otimização" bastante ambíguo. Se algumas mudanças no nível da instrução no layout da memória e nos padrões de acesso tornam algo 80 vezes mais rápido de um profissional disciplinado que mede seus pontos de acesso sem reduzir a complexidade algorítmica, isso é uma "micro-otimização"? Para mim, é uma "mega otimização" para tornar algo 80 vezes mais rápido em um caso de uso do mundo real. As pessoas tendem a falar sobre essas coisas, como essas otimizações têm efeitos microscópicos.

Não estou mais trabalhando no gamedev, mas trabalho em VFX em áreas como rastreamento de caminhos, e já vi muitas implementações de árvores BVHs e KD por aí que processam ~ 0,5 milhão de raios por segundo em uma cena complexa (e isso é com avaliação multithread). Grosso modo, eu costumo ver uma implementação direta de uma BVH em um contexto de rastreamento de raios abaixo de 1 milhão de raios / s, mesmo com avaliação multithread. Exceto Embree tem um BVH que pode processar mais de 100 milhões de raios na mesma cena com o mesmo hardware.

Isso se deve inteiramente às "micro-otimizações" de que o Embree é 200 vezes mais rápido (mesmo algoritmo e estrutura de dados), mas é claro que o motivo é muito mais rápido, porque os desenvolvedores da Intel por trás dele são profissionais que se apóiam em seus perfis, medições e realmente sintonizou as áreas que importavam. Eles não estavam mudando o código de uma maneira ou de outra, cometendo alterações que fizeram 0,000000001% de melhorias com o custo de manutenção significativamente degradante. Essas foram as otimizações muito precisas aplicadas em mãos criteriosas - elas podem ter sido microscópicas em termos de foco, mas macroscópicas em termos de efeito.

Naturalmente, com os requisitos de taxa de quadros em tempo real dos jogos, dependendo de como você trabalha com alto nível ou baixo nível com o mecanismo de jogo (mesmo os jogos feitos com UE 4 são geralmente implementados pelo menos parcialmente em scripts de alto nível, mas não, digamos, as partes mais críticas do mecanismo de física), as micro-otimizações se tornam um requisito prático em determinadas áreas.

Outra área muito básica que nos cerca diariamente é o processamento de imagens, como desfocar imagens de alta resolução em tempo real e talvez fazer outros efeitos nelas como parte de uma transição que provavelmente já vimos em algum lugar, talvez até um efeito do sistema operacional. Você não pode necessariamente implementar essas operações de imagem do zero, percorrendo todos os pixels de uma imagem e esperar resultados em tempo real com taxas de quadros correspondentes. Se é CPU, geralmente observamos o SIMD e alguns micro-ajustes, ou observamos os shaders de GPU, que tendem a exigir um tipo de mentalidade de nível micro para escrever com eficiência.

Em caso afirmativo, à medida que o hardware melhora, devemos esperar que idiomas de nível superior assumam o controle da indústria de jogos?

Duvido que apenas os avanços do hardware possam fazer isso, porque, à medida que o hardware avança, o mesmo acontece com as instruções e a tecnologia (ex: física na GPU), técnicas e expectativas dos clientes quanto ao que eles querem ver e competição. maneiras pelas quais os desenvolvedores frequentemente voltam a entrar em nível mais baixo novamente, como no caso dos desenvolvedores da Web que agora escrevem shaders GLSL de baixo nível no WebGL (o desenvolvimento da Web desse tipo específico é provavelmente ainda mais baixo do que há uma ou duas décadas atrás, como o GLSL é uma linguagem do tipo C de nível extremamente baixo, e eu nunca imaginaria uma década ou duas atrás que alguns desenvolvedores da Web aceitariam escrever tais shaders de GPU de baixo nível).

Se houver uma maneira de as áreas críticas de desempenho mudarem para linguagens de nível superior, terá que vir mais do software, compiladores e ferramentas que temos disponíveis a meu ver. O problema para mim em um futuro próximo não é o hardware não ser suficientemente poderoso. Tem mais a ver com a forma como não conseguimos encontrar maneiras de falar com mais eficiência a cada vez que ela muda e avança sem voltar ao seu próprio idioma. Na verdade, é o ritmo acelerado em que o hardware muda que torna a programação de alto nível ilusória para essas áreas, como eu o vejo, pois se, hipoteticamente, nosso hardware parar de avançar do nada nas décadas seguintes,

É engraçado nos dias de hoje, quando estou trabalhando em áreas genuínas de desempenho crítico, preciso pensar em um nível mais baixo do que comecei (apesar de ter começado na era do Borland Turbo C DOS). Porque naquela época o cache da CPU era quase inexistente. Era basicamente apenas DRAM e registros, o que significava que eu poderia me concentrar mais na complexidade algorítmica e escrever estruturas vinculadas como árvores de uma maneira muito direta, sem sofrer muito impacto no desempenho. Atualmente, os detalhes de baixo nível do cache da CPU dominam meu pensamento quase tanto quanto o próprio algoritmo. Da mesma forma, temos máquinas com vários núcleos que precisam nos fazer pensar em multithreading, atômica e mutexes, segurança de threads e estruturas de dados simultâneas, e assim por diante, o que eu diria que é, em muitos aspectos, um foco de nível muito mais baixo (como in, não tão humanamente intuitivo) do que quando comecei.

Estranhamente, isso me parece muito verdadeiro agora. Acho que estou mais impactado pelas complexidades e detalhes subjacentes e de baixo nível do hardware hoje do que há 30 anos, tentando o meu melhor para tirar os óculos de nostalgia. É claro que talvez tenhamos conversado um pouco sobre montagem aqui e tivemos que lidar com alguns detalhes sangrentos, como o XMS / EMS. Mas, na maioria das vezes, eu diria que havia menos complexidade e conhecimento de hardware e compilador que eu exigia naquela época do que hoje quando trabalho em áreas críticas de desempenho. E isso quase parece verdadeiro para toda a indústria se deixarmos de lado como escreverif/else instruções de uma maneira um pouco mais humanamente legível e considere o quanto as pessoas em geral hoje em dia estão pensando mais nos detalhes de nível inferior do hardware (de vários núcleos a GPUs, a SIMD no cache da CPU e os detalhes internos de como seus compiladores / intérpretes / bibliotecas funcionam e assim por diante).

Alto nível! = Menos eficiente

Voltando a esta pergunta:

Em caso afirmativo, à medida que o hardware melhora, devemos esperar que idiomas de nível superior assumam o controle da indústria de jogos?

Para mim, não é sobre hardware. É sobre otimizadores e ferramentas. Quando eu comecei, as pessoas praticamente escreveram todos os jogos de console em assembly, e havia uma vantagem de desempenho genuína, especialmente devido à falta de compiladores de qualidade gerando 6502.

À medida que a otimização dos compiladores C ficou mais inteligente em suas otimizações, eles começaram a chegar a um ponto em que o código de nível superior escrito em C estava rivalizando e, ocasionalmente, até superando o código escrito pelos melhores especialistas em montagem em muitas áreas (embora nem sempre), e isso fez com que fosse então um acaso adotar C para pelo menos a maior parte da codificação de um jogo. E uma mudança semelhante aconteceu gradualmente em algum momento com o C ++. A adoção do C ++ foi mais lenta, pois acho que o aumento da produtividade de ir de assembly para C provavelmente poderia chegar a um acordo unânime dos gamedevs que escrevem jogos não triviais inteiramente no ASM, em vez de passar de C para C ++.

Mas essas mudanças não vieram do hardware se tornar mais poderoso, mas os otimizadores dessas linguagens tornando o nível mais baixo em grande parte (embora nem sempre inteiramente, há alguns casos obscuros) obsoletos.

Se você pode imaginar um cenário hipotético em que poderíamos escrever código no código de mais alto nível imaginável, sem se preocupar com multithreading ou GPUs ou falhas de cache ou algo assim (talvez nem mesmo estruturas de dados específicas), e o otimizador era como inteligência artificial inteligente e capaz de descobrir os layouts de memória mais eficientes, reorganizando e compactando nossos dados, calculando que ele poderia usar alguma GPU aqui e ali, paralelizar algum código aqui e ali, usar algum SIMD, talvez criar um perfil próprio e continuar otimizando ainda mais seu IR como seres humanos respondendo a pontos críticos de criação de perfil, e isso foi feito de uma maneira que supera os melhores especialistas do mundo, seria um acéfalo para quem trabalha nas áreas mais críticas de desempenho adotá-lo ... e isso é um avanço provenientes de otimizadores ridiculamente inteligentes, e não de hardware mais rápido.

Dragon Energy
fonte
0

Em C #, a "otimização micro" é desaprovada, rara e geralmente uma perda de tempo. Este não parece ser o caso no desenvolvimento de jogos.

Você tem um problema de terminologia aqui. Você está usando as palavras corretamente, mas desenvolvedores de jogos e pessoas de negócios estão usando o mesmo termo de duas maneiras muito diferentes.

Para os negócios, "micro otimização" significa acelerar um passo muito pequeno no processo geral de negócios implementado pelo software. O motivo pelo qual isso é mal visto é tipicamente um dos seguintes:

  1. Gastos extras entregando o mesmo valor comercial, a alguns segundos de velocidade mais rápida. O dinheiro economizado nas melhorias de velocidade vem de um conjunto diferente de dinheiro (o tempo do usuário), de modo que a empresa geralmente não se beneficia do esforço que gasta, o cliente às custas da empresa.
  2. Normalmente, os programadores de negócios têm pouca visibilidade no processo geral de negócios, portanto, a otimização de uma única etapa pode não trazer bons benefícios para o processo geral. Por exemplo, se você tornar 3% do processo 10x mais rápido, acelerará todo o processo 2,7%.
  3. Normalmente, os negócios têm uma grande lista de trabalho restante que tem algum valor comercial e priorizariam adicionar esse valor em vez de fornecer o mesmo valor em um (provavelmente) tempo menor.

O desenvolvimento de jogos é uma fera diferente. "micro otimização" está economizando uma pequena quantidade de tempo em uma função ou rotina.

  1. Os sistemas de jogos tendem a ser mantidos no ciclo de renderização. Atualmente, o padrão-ouro é de 60 quadros por segundo, então tudo o que será calculado precisa ser feito e renderizado na tela em 1/60 de segundo.
  2. Isso significa que geralmente as mesmas rotinas são chamadas de milhares a centenas de milhares de vezes ao longo de um jogo. Assim, uma melhoria de 10x em uma única função é aumentada em valor pelo número de vezes que os benefícios da melhoria serão sentidos.
  3. A falha em atingir a taxa de renderização afeta a apresentação do jogo. O vídeo ficará instável, os personagens serão animados com pulos e saltos em vez de movimentos fluidos. Isso imediatamente tira o jogador da imersão do jogo e entra no campo de questionar o valor do jogo.

Portanto, nos negócios, ninguém se importa se a forma de um processo de negócios em quatro etapas se apresentar em 0,6 segundos ou 0,5 segundos. Durante os jogos, importa-se se uma rotina de 200ms pode ser reduzida à execução em 100ms.

É tudo sobre o valor entregue ao cliente, as necessidades do cliente e a relação custo-benefício da mudança.

Edwin Buck
fonte
-1

Tem a ver com o motivo pelo qual essa ferramenta foi selecionada para um trabalho específico.

Os golfistas ficam obcecados com a direção e a força que aplicam com um taco, não tanto quando estão usando o motorista.

Por quê? Porque eles são diferentes tipos de tiros. Para um passeio, você quer pegá-lo no fairway com a distância máxima. Para uma tacada leve, você deseja colocá-lo exatamente no buraco.

O mesmo se aplica aqui. Os desenvolvedores de jogos escolhem o C ++ porque isso lhes dá controle sobre o desempenho de diferentes operações. Se você escolheu isso, vai querer aproveitá-lo.

JohnMcG
fonte
-3

A maioria dos aplicativos de negócios é escrita como ferramentas internas. As expectativas sobre a usabilidade dessas ferramentas são muito menores do que no caso de software vendido a clientes em massa. É bastante comum que um aplicativo comercial interno tenha menus e diálogos que reajam lentamente aos cliques do mouse, janelas que são redesenhadas com atraso ou até uma GUI escrita em Swing (o horror!). Isso devido a várias razões (é mais importante que o software seja personalizável do que muito "rápido", os usuários do software não têm escolha entre usar ou não o software em questão, as pessoas que fazem o software decisão de instalar o software não o utilize por si próprio ...). A consequência de tudo isso é que os desenvolvedores dessas ferramentas não passam muito tempo otimizando a capacidade de resposta do aplicativo, mas se preocupam muito com a extensibilidade e o número de recursos. Base de clientes diferente => objetivos de projeto diferentes => metodologia diferente.

Observe que um aplicativo de negócios direcionado a um público em massa, como o Excel, é fortemente otimizado.

quant_dev
fonte