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 ...
fonte
Respostas:
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:
É por isso que o código que otimiza o desempenho do processamento não agrega muito valor.
A principal consideração é:
fonte
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.
fonte
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.
fonte
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.
fonte
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
"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.
fonte
Os jogos constantemente fazem grandes quantidades de processamento em segundo plano. Aplicativos de negócios não.
fonte
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.
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 escrever
if/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:
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.
fonte
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:
O desenvolvimento de jogos é uma fera diferente. "micro otimização" está economizando uma pequena quantidade de tempo em uma função ou rotina.
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.
fonte
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.
fonte
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.
fonte