Sou estudante do segundo ano da Computer Games Technology. Recentemente, terminei meu primeiro protótipo do meu "tipo" de descobridor próprio (que não usa A * em vez de uma abordagem geométrica / reconhecimento de padrões, o descobridor só precisa do conhecimento sobre o terreno que está em sua visão para tomar decisões, porque eu queria uma IA que pudesse realmente explorar, se o terreno já for conhecido, ele percorrerá o caminho mais curto com facilidade, porque o pathfinder tem uma memória de nós).
De qualquer forma, minha pergunta é mais geral: como começo a otimizar algoritmos / loops / for_each / etc. usando o Assembly, embora dicas gerais sejam bem-vindas. Estou procurando especificamente bons livros, porque é realmente difícil encontrar bons livros sobre esse assunto. Existem alguns artigos pequenos por aí como este , mas ainda não há conhecimento suficiente para otimizar um algoritmo / jogo ...
Espero que haja um bom livro moderno por aí, que eu simplesmente não consegui encontrar ...
fonte
Respostas:
Eu serei o oposto aqui e direi que nunca é cedo para aprender sobre otimizações, especialmente otimizações de montagem e, mais importante, depuração na montagem. Eu acredito que você obterá o benefício máximo disso se for um estudante (porque então você tem muito pouco a perder [isto é, tempo / dinheiro]) e tudo a ganhar.
Se você está no setor e não tem a tarefa de mexer na montagem, não o faça. Caso contrário, se você é um estudante ou tem tempo em geral, eu encontraria tempo para aprender a desmontar programas e ver se consigo encontrar uma solução melhor que o compilador. Se não posso, quem se importa! Eu apenas aprendi a escrever, assim como o compilador, e isso é uma enorme vantagem quando você se depara com um bug no código de liberação (sem símbolos de depuração) e olhando para a desmontagem porque é a única coisa que você pode ver.
A resposta
Este é um dos melhores recursos que encontrei para aprender sobre otimizações.
http://www.agner.org/optimize/
O discurso retórico
Se você ler alguns artigos de grandes desenvolvedores (por exemplo, o raciocínio por trás da criação do EASTL e uma inspeção mais detalhada do código o levará a comentários como o fez, porque o GCC é péssimo em incluir essa declaração if que informará o que a maioria dos as pessoas dizem que você confia que o compilador nem sempre está certo, ESPECIALMENTE no desenvolvimento de jogos) e, em seguida, colocam os pés no setor, você descobrirá que as otimizações são comuns e saber o que significa a saída da montagem é uma grande vantagem. Além disso, as pessoas parecem não perceber (especialmente no stackoverflow) que a criação de perfis de jogos é muito difícil e nem sempre precisa.
Há uma ressalva. Você pode gastar tempo otimizando algo e depois perceber que foi um desperdício de tempo. Mas o que você aprendeu? Você aprendeu a não repetir o mesmo erro em uma circunstância semelhante.
O que o SO está adotando agora é, na minha opinião, uma posição religiosa para a afirmação não otimizar até você criar um perfil e não se preocupe, o compilador sabe melhor do que você . Isso dificulta o aprendizado. Conheço especialistas do setor que recebem muito dinheiro bom (e quero dizer MUITO bom dinheiro) para mexer na montagem para otimizar o jogo e depurá-lo porque o compilador é ruim ou simplesmente não pode ajudá-lo, porque, bem, ele não pode (falhas relacionadas à GPU, falhas nas quais é impossível ler os dados envolvidos em um depurador etc. etc.)!
E se alguém que adora fazer isso, ainda não o percebeu completamente, fizer a pergunta aqui e for desligado / desabilitado pelas muitas respostas que o compilador conhece melhor que você! e nunca se torna um daqueles programadores altamente pagos?
Um pensamento final. Se você começar a fazer isso mais cedo, descobrirá que em breve começará a escrever um código que, na pior das hipóteses, não possui melhorias de desempenho porque o compilador a otimizou da mesma maneira ou, na melhor das hipóteses, tem algumas melhorias de desempenho porque agora o compilador pode otimizá-lo . Em ambos os casos, tornou-se um hábito e você não é mais lento ao escrever código dessa maneira do que antes. Alguns exemplos são (existem muitos mais):
EDIT: Atualização após mais 8 anos no setor. Aprenda montagem. Aprenda como os otimizadores funcionam e a montagem que eles geram (CompilerExplorer é uma ótima ferramenta para isso). Eu já deparei com inúmeras falhas nas compilações de teste (compilações otimizadas para testes internos) nas quais você não pode confiar no depurador, mesmo com símbolos de depuração. O compilador otimizou muitas coisas e o assembly é sua única fonte de informações valiosas para encontrar o bug do despejo de memória. Cada build leva 30 a 40 minutos se você tiver sorte e for o primeiro na fila de build - portanto, você não pode confiar em algumas técnicas tradicionais para isolar o bug. O multiplayer piora as coisas. Conhecer a montagem e ler a montagem otimizada simplesmente o tornará melhor e, em última análise, mais valioso para a equipe.
fonte
A primeira dica que você terá é essa - não.
Os compiladores modernos são realmente muito bons em otimizar o código e terão muito mais chances de fazer um trabalho melhor do que qualquer linguagem assembly autolaminada que você possa escrever.
A exceção seria qualquer caso específico em que você determinou com certeza que o compilador está fazendo um trabalho ruim de otimização, então essa é a segunda dica. Não há diretrizes gerais aqui, você precisa conhecer seu próprio código, saber o que está fazendo, ser capaz de saltar para uma desmontagem e ser capaz de determinar com absoluta certeza que o compilador está fazendo um mau trabalho.
Mesmo neste caso, você ainda pode não querer. Você precisa ter certeza de que não haverá nenhuma sobrecarga de manutenção em andamento para você. Você pode voltar a esse código em seis meses e modificar parte dele, ou pode encontrar um bug extremamente sutil que será mais difícil de corrigir em uma versão em linguagem assembly. Mesmo que você ache que já resolveu todos os problemas, uma vez que seu programa vai para os erros públicos, você nunca pensou que isso poderia acontecer, se tornará uma realidade para você. Isso é bastante revelador (e uma experiência humilhante).
E mesmo que você esteja feliz em aceitar isso, você ainda pode achar que não há absolutamente nenhuma melhoria mensurável de desempenho, pois seu principal gargalo pode estar em algum lugar completamente diferente em seu programa. Então, isso me leva de volta ao número 1 novamente. Não.
fonte
Normalmente, a otimização sólida não depende do uso do Assembly ou da micro-otimização com código em linguagens de nível superior. Se você ler muitos trabalhos de pesquisa (como eu faço - ou tentar!), Verá que muitas vezes as melhorias feitas nos algoritmos estão em um nível conceitual mais amplo, "qualitativo", em vez de mais "quantitativo" nível de micro-otimização. Eu enfatizaria que os ganhos em ordem de magnitude são mais prováveis de se observar algoritmos desse ponto de vista ou de vetorizar / paralelizar soluções existentes.
Dito isto, recentemente me deparei com isso , o que pode ser um bom caminho para o aprendizado do ASM x86 especificamente para desenvolvedores de jogos.
TERMO ADITIVO
Duas fontes em cima da minha cabeça:
Além disso, a leitura de trabalhos de pesquisa é uma excelente maneira de seguir os processos de pensamento dos sábios, pois otimizam os algoritmos para obter melhor desempenho. Na maioria das vezes, os ganhos são vistos por:
A pesquisa em leitura também mantém você na vanguarda do seu campo, em vez de esperar que esse conhecimento seja filtrado pelo setor.
fonte
Eu acho que pode ser muito cedo.
De qualquer forma, é importante entender que o próprio compilador não produz código mais lento que o equivalente ao assembly, você não obtém desempenho simplesmente escrevendo o mesmo código de assembly que o compilador produziria.
Para começar, concentre-se em otimizações sem montagem. Igor Ostrovsky tem alguns bons artigos que demonstram alguns dos princípios básicos: http://igoro.com/archive/fast-and-slow-if-statements-branch-prediction-in-modern-processors/
Observe que erros de previsão de ramificação e falhas de cache são contra os quais você deve otimizar principalmente, mesmo se você tiver que pagar fazendo algumas operações aritméticas extras, geralmente vale a pena evitar uma ramificação imprevisível ou ler aleatoriamente a partir de muita memória.
E, claro, o mais importante, otimize seu algoritmo primeiro. Uma implementação lenta de um algoritmo rápido quase sempre será mais rápida do que uma implementação rápida de um algoritmo lento.
fonte
Este livro é excepcionalmente bom para um livro de texto. Mas não é voltado especificamente para a otimização. Linguagem Assembly para processadores x86, 6ª edição
É mais sobre ensinar os fundamentos da montagem, usando o MASM. Depois, no final do livro, ele aborda como alinhar o assembly com o c ++ e integrá-lo a programas maiores.
Coloquei isso aqui porque faz sentido aprender os fundamentos da montagem antes de aprender como otimizar os programas com ela.
Gosto deste livro porque o Irvine ensina como usar as ferramentas necessárias para escrever programas de masm. Ele explica especificamente como usar o IDE (Visual Studio C ++) e o depurador. Cada capítulo possui alguns vídeos dedicados à solução de problemas. Algumas dessas informações estão disponíveis gratuitamente no site listado.
fonte