data = "2021-01-16T02: 50: 00 + 05: 30"
title = "Lançamento de novo recurso - Reescrita do cache de buffer"
autor = "CaptV0rt3x"
Olá, yuz-ers! A continuação da nossa [grande reescrita de código anterior] (
https://yuzu-emu.org/entry/yuzu-tcr/) está finalmente aqui: a Reescrita do Cache de Buffer! Este empreendimento massivo não apenas melhora o desempenho significativamente, mas também simplifica o código para nossos desenvolvedores. Agora vamos começar este artigo!
Então, o que um Buffer Cache faz?
Como o nome indica, um Cache de Buffer - bem - armazena em cache (armazena) buffers. Isso pode não ter feito muito sentido, mas é o que faz.
Na programação de gráficos, para a GPU renderizar qualquer coisa, ela precisa de dados como posição, cor, etc. Normalmente, esses dados são fornecidos pelo aplicativo. Mas quando temos grandes aplicativos lidando com grandes volumes de dados, fica cada vez mais difícil fornecer constantemente a GPU com dados e renderizá-los. Conseqüentemente, objetos de buffer foram introduzidos.
Objetos de buffer são objetos de memória que armazenam os dados de renderização na memória da GPU - aumentando, assim, a capacidade de reutilização de forma significativa. Existem vários tipos de vínculos, comumente chamados de tipos de buffer, como buffers de índice, buffers de vértice e buffers uniformes (entre outros). Isso melhora o desempenho de renderização porque os dados agora estão prontamente disponíveis para uso pela GPU.
### Buffer Cache do yuzu
Voltando ao caso de yuzu, yuzu inicialmente herdou um buffer de fluxo - originalmente implementado para [Citra] (
https://citra-emu.org) por [degasus] (
https://github.com/degasus). Um buffer de fluxo funciona em um ciclo de modificação / uso, o que significa que você atualiza frequentemente o objeto de buffer e vincula essa região. [Rodrigo] (
https://github.com/ReinUsesLisp) e [Blinkhawk] (
https://github.com/FernandoS27) posteriormente implementaram nosso cache de buffer existente para trabalhar junto com o buffer de fluxo. Não havia nada inerentemente errado com isso; os buffers de fluxo são, na verdade, uma das maneiras mais rápidas de fazer upload de dados para a GPU. Mas quando [Rodrigo] (
https://github.com/ReinUsesLisp) traçou o perfil do yuzu, o gerenciamento de cache e as cópias de upload eram algo que continuava aparecendo lento.
{{<mensagem "Criação de Perfil">}}
Na engenharia de software, o profiling ("perfil de programa", "perfil de software") é uma forma de análise dinâmica de programa que mede, por exemplo, o espaço (memória) ou complexidade de tempo de um programa, o uso de instruções específicas ou a frequência e duração das chamadas de função. Mais comumente, as informações de perfil servem para auxiliar na otimização do programa. {{</ mensagem>}}
O problema está no fato de que os jogos não estão exatamente transmitindo dados o tempo todo. Portanto, o uso de uploads imediatos (em OpenGL) e cache mais rápido resultou em um desempenho muito melhor do que ter um buffer de fluxo e armazenar grandes recursos em cache, pelo menos para a Nvidia. Após testes adicionais, descobrimos que isso acabou sendo falso para drivers não Nvidia em OpenGL (AMD, Intel e Mesa) e, portanto, tivemos que adicionar um buffer de fluxo para pequenos uploads nesses drivers.
## O que mudou agora?
Os objetivos do projeto técnico para a Reescrita do Cache de Buffer eram as mesmas de nossa Reescrita do Cache de Textura.
- Código de limpeza: Chega de chamadas de funções virtuais ou ponteiros compartilhados, o que significa manutenção mais fácil no futuro.
- Maior eficiência e melhor desempenho. Resolver qual buffer existia em qual região de memória era uma operação muito cara em nossa antiga implementação de cache de buffer. É por isso que o buffer de fluxo existia - para torná-lo mais rápido.
O novo Buffer Cache melhorou muito o rastreamento dos vários buffers que armazena em cache. Na nova implementação, quando buffers são criados na memória, eles são forçosamente alinhados a 4K [páginas] (
https://en.wikipedia.org/wiki/Page_ (computer_memory)) (4096 bytes - começando em zero).
E para saber com eficiência qual buffer existe em qual endereço, o cache usa um array plano de 32 MiB de largura para traduzir da página atual da CPU onde o buffer existe para qual buffer reside nele.
por exemplo se o endereço for 4096 ou 7000, é a página 1 e se for 8192, é a página 2.
Assim, o novo Buffer Cache pode rastrear quais páginas de um buffer foram modificadas em uma base de página em vez de ser um estado binário.
Imagine se um buffer tem um tamanho de 524288 bytes e um jogo modifica apenas 1 byte do buffer. Como os buffers agora estão alinhados a 4.096 bytes, conforme mencionado anteriormente, apenas esses 4.096 bytes são carregados para a GPU. A mesma coisa acontece quando a GPU tenta atualizar o cache com dados modificados pela CPU.
Esse rastreamento é feito usando arrays de bits nos buffers. Cada valor representa o estado da página - 1 sendo modificado, 0 sendo limpo. Manter as coisas em uma matriz de bits nos permite usar operações de bits eficientes como
std :: país_zero
e
std :: país_one
(C ++ 20). Isso resulta em menos instruções produzindo os mesmos resultados (muito mais rápido).
## Tudo bem, vamos falar de ganhos de desempenho!
Alguns problemas gráficos foram corrigidos devido ao retrabalho - causa desconhecida desempenho moar inserir gráficos e capturas de tela
## Fin
Com isso, concluímos nossa cobertura do novo Buffer Cache Rewrite. Como sempre, gostaríamos de lembrar aos usuários que os recursos lançados em [Early Access] (
https://yuzu-emu.org/help/early-access/) ainda estão sendo trabalhados.
Se você encontrar quaisquer bugs, problemas, perda de desempenho, travamentos ou regressões com este novo recurso, por favor entre em contato conosco em nosso [servidor Discord] (
https://discord.com/invite/u77vRWY) e compartilhe suas descobertas.
Até a próxima, <br> - equipe de desenvolvimento do yuzu!