Quanta montagem é realmente usada no código do jogo moderno? [fechadas]

21

Em média, com que frequência o assembly é usado no código de jogo moderno?

Especificamente em plataformas que já possuem bons compiladores C ++, como x86, PPC ou ARM - porque eu assumo que jogos em sistemas embarcados fazem uso extensivo de montagem.

Legião
fonte
4
O C ++ não compila no assembly - ele compila no código da máquina. A linguagem assembly é uma maneira de especificar diretamente exatamente qual código de máquina você deseja gerar.
Kylotan
6
C ++ (geralmente) não é realmente compilado para montagem, é compilado diretamente no código da máquina. A pergunta provavelmente está se referindo à quantidade de montagem manuscrita vinculada a um projeto ou escrita como montagem embutida.
1
Independentemente disso, acho que não há uma resposta prática e útil para essa pergunta. Depende basicamente de fatores semelhantes, muitos dos quais são subjetivos (ou seja, as opiniões dos autores do código).
1
Atualmente
4
@ Legion - você pode fazer com que o compilador / IDE emita montagem, mas isso não significa que o compilador produz montagem como parte de um processo normal de compilação. Não é necessário fazê-lo e, consequentemente, a maioria não.

Respostas:

29

A resposta depende um pouco do que você quer dizer com "jogo" e "usado". Assumirei que "usado" significa "escrito durante o curso do projeto de jogo específico".

Na minha experiência e dados anedóticos de pessoas com quem conversei:

  • em jogos baseados em navegador? Nenhum.
  • em jogos típicos de PC? Nenhum. (Mas você pode ver alguns nas bibliotecas de baixo nível.)
  • em jogos para iOS e Android? Nenhum.
  • Jogos para PC "AAA" e jogos de console? Talvez um pouco, talvez 0,05% da base de código. (Com um pouco mais nas bibliotecas.)

O conhecimento da linguagem assembly não é esperado para o trabalho na indústria de jogos, mas, dependendo do tipo de jogo que você faz, pode ser vantajoso.

Costumava haver um argumento de que o compilador faz um trabalho melhor na otimização do código C do que um humano faria com um assembly escrito à mão. Geralmente isso é verdade, às vezes é falso. Hoje em dia, uma combinação de crescente complexidade da CPU e a necessidade de expandir '' (ou seja, separar processadores) significa que os esforços de otimização são geralmente gastos em outros lugares.

Nos últimos anos, a única vez que vi assemblagem no código do jogo foram __asm int 3declarações para forçar pontos de interrupção, e meu único uso pessoal de assemblagem foi na desmontagem de uma função para diagnosticar bugs incomuns.

Kylotan
fonte
1
E as instruções do SSE?
Legion
4
@Legion, as pessoas geralmente escrevem código SSE usando bibliotecas intrínsecas ou matemáticas que envolvem o material SSE ou em uma minilinguagem especializada projetada especificamente para compilar no SSE, como o ispc . Escrever a montagem diretamente ainda é bastante raro.
Nathan Reed
1
Em relação aos jogos para iOS: Se bem me lembro, a biblioteca 3D / Math Oolong usou alguma montagem ARM embutida. Isso não é mais necessário desde que a Apple lançou o framework Accelerate.
Nicolas Miari
Concordo com Nathan - SSE e otimizações semelhantes específicas de instruções geralmente existem nas bibliotecas (uma vez que geralmente são os únicos lugares em que o benefício total ganho vale o esforço realizado).
Kylotan
26

A maior parte do código de alto desempenho nos modernos jogos de console é escrita usando uma espécie de meio termo entre assembly e C ++: intrínsecas do compilador . Essas construções parecem e analisam como funções C ++, mas na verdade são traduzidas em instruções de máquina única . Assim, por exemplo, minha função "prender cada valor do vetor V a ser> = ae <= b" se parece com

// for each v.x, ensure v.x >= a.x && v.x <= b.x
inline __m128 ClampSIMD( const __m128 &v, const __m128 & a, const __m128 & b )
{
    return _mm_max_ps( a, _mm_min_ps( v, b ) );
}

Em funções como essas, ainda estou pensando em termos das instruções específicas da máquina , mas tenho a conveniência de escrevê-las em C, para que não precise me preocupar com a coloração e programação do registro, as operações de carregamento e outros detalhes chatos.

Você ainda precisa estar ciente de quais instruções a CPU suporta, especialmente porque os compiladores modernos são péssimos na vetorização de código, em comparação com a capacidade de um ser humano inteligente fazer o trabalho. Às vezes, detalhes sutis de como você organiza seu código podem ter implicações enormes para o desempenho que não são óbvias sem entender o que a máquina está fazendo.

Embora não possamos codificar no assembly, ainda assim depuramos no assembly. A otimização dos compiladores reorganiza agressivamente o código de maneiras que os depuradores não conseguem acompanhar, com tanta freqüência ao depurar um "modo de liberação" que a melhor coisa a fazer é abrir o desmontador e rastrear o código dessa maneira. Essa palestra da GDC sobre "Depuração forense" de falhas ilustra muitos dos porquês e comos da depuração nesse nível.

Crashworks
fonte
3
+1 simplesmente porque o Crashworks é bem conhecido no SO como sendo "aquele cara que escreve um código otimizado para jogos de baixo nível" - se alguém conhece esse tópico, é ele.
BlueRaja - Danny Pflughoeft
@ BlueRaja-DannyPflughoeft "Bem conhecido"? Fico lisonjeado! =) Uma coincidência divertida, à luz dos comentários de Nathan Reed, é que eu aprendi muitas das minhas habilidades de otimização de baixo nível na Naughty Dog.
Crashworks
Em outros lugares, também ouvi a importância do assembly na depuração. Então, eu vou aprender. Obrigado pela compreensão e links.
Legion
7

Os problemas que costumavam exigir montagem manual são cada vez menos numerosos. O que você "pode" ganhar em velocidade, perde em legibilidade e na capacidade de depurar. Isso também deve ser feito apenas como uma das últimas etapas de otimização em seções de código, pois na maioria dos casos os problemas de velocidade não são algo que não possa ser melhorado com a montagem. Atualmente, as CPUs ficaram muito mais rápidas, enquanto as velocidades de memória não, geralmente é mais importante controlar como os dados fluem através da CPU do que qualquer outra coisa.

Com os compiladores modernos, eles também acham difícil otimizar o código de montagem, pois precisam lidar com os registros que você tocou e geralmente não podem reordenar as instruções no código artesanal. Para reduzir a necessidade de montagem, também há agora intrínseca que ajudam a obter acesso a conceitos de baixo nível, mas de uma maneira que seja compiladora e permita que eles trabalhem com você e não contra.

Com isso dito, a SPU no PS3 é uma área em que as pessoas ainda precisam usar a montagem para obter o máximo do processador, com pipelining de instruções manuais, por exemplo, conforme explicado aqui .

Roger Perkins
fonte
1
Mesmo na PS3, as pessoas geralmente não muito programa na montagem nua. Existe uma ferramenta que permite escrever código na sintaxe de montagem, onde você especifica as instruções da máquina, mas realiza a alocação de registros, o agendamento de instruções e o pipelining de loop para você. Bem, talvez o Naughty Dog realmente faça tudo manualmente, mas mesmo a maioria dos desenvolvedores de PS3 SPU não faz isso na minha experiência. :)
Nathan Reed
1
@NathanReed Nos dias de PS2, o pipelining de loop manual fazia parte da entrevista do programa da Naughty Dog.
Crashworks
-1

O fato é que vivemos em um mundo multiplataforma, e partes do nosso código de jogo precisam ser adaptadas à plataforma local - não é necessário, mas existem benefícios se tirarmos proveito do material de hardware local!

Não se trata de jogos ou lógica de jogos, trata-se de localidade de hardware para obter o desempenho ideal do código em que a lógica do jogo depende, podemos de fato agrupar seções de código, por exemplo, usando macros, de modo que exista um código-fonte com bom desempenho no plataforma contra a qual foi construído.

Homer
fonte