AMD decide desativar o loop buffer do Zen 4
(chipsandcheese.com)- Em uma nova BIOS da ASRock B650 PG Lightning, o loop buffer do Zen 4 deixou de ser observado como fonte de micro-ops, e ao voltar para uma BIOS anterior ele é reativado
- Essa estrutura parece ser um recurso para processar repetidamente pequenos loops no frontend e reduzir consumo de energia, com estimativa de 144 entradas em thread única e 72 entradas por thread com SMT de 2 threads
- No SPEC CPU2017, a diferença de pontuação total entre loop buffer ativado e desativado fica em menos de 1%, então o impacto no desempenho geral parece muito pequeno
- Com o loop buffer desligado, o Zen 4 passa a fornecer mais micro-ops pelo op cache, e como a largura de banda do op cache é suficiente em relação ao throughput do backend, isso dificilmente vira um gargalo de frontend
- O motivo da desativação e o impacto real em consumo de energia são incertos, mas como a AMD quase não documentou nem divulgou esse recurso limitado, a maioria dos usuários e desenvolvedores dificilmente perceberá a mudança
Papel e limitações do loop buffer no Zen 4
- O loop buffer é uma estrutura no frontend da CPU que guarda um pequeno conjunto de instruções já buscadas, permitindo desligar parte das etapas do frontend quando pequenos loops são executados repetidamente
- Pode ajudar a reduzir consumo de energia
- Também pode melhorar desempenho ao contornar limitações do frontend
- É uma técnica usada há muito tempo em núcleos da Intel, Arm e AMD
- O Zen 4 parece ser o único caso de um núcleo AMD de alto desempenho com loop buffer
- O Processor Programming Reference do Zen 4 cita o loop buffer, junto com o op cache e os decodificadores, como fonte de dispatch de micro-ops
- Pelos experimentos com contadores de desempenho, a capacidade é estimada da seguinte forma
- 144 entradas em execução com thread única
- 72 entradas por thread com SMT de 2 threads ativo, em divisão estática
- Se houver CALL/RET dentro do loop, o loop buffer do Zen 4 não consegue capturar esse loop
- O guia de otimização do Zen 4 da AMD não trata do loop buffer e apenas recomenda manter regiões de código quente dentro da capacidade do op cache
O loop buffer sumiu após uma atualização de BIOS
- Após atualizar a ASRock B650 PG Lightning para a BIOS 3.10, o monitoramento de desempenho por hardware mostrou que o loop buffer não faz dispatch de micro-ops
- Ao voltar para a BIOS 1.21, o loop buffer volta a ficar ativo
- A desativação parece ter ocorrido entre o AGESA 1.0.0.6 da BIOS 1.21 e o AGESA 1.2.0.2a da BIOS 3.10
- A AMD aplicou essa mudança sem anúncio ou divulgação específica
- Em discussões paralelas com funcionários da AMD no Hot Chips 2024, o loop buffer foi descrito principalmente como um recurso de otimização de energia
Pequena diferença de desempenho no SPEC CPU2017
- A pontuação total dos suites de inteiros e ponto flutuante do SPEC CPU2017 difere em menos de 1% entre loop buffer ativado e desativado
- O ganho de desempenho com SMT também não é afetado pela desativação do loop buffer
- O impacto pequeno acontece porque o op cache do Zen 4 já oferece mais largura de banda do que o estágio de rename/allocate do backend consegue consumir
- Mesmo com o loop buffer ligado, os contadores de desempenho mostram que apenas uma pequena fração dos micro-ops vem dele
- Também não foram observadas grandes perdas em benchmarks individuais
- O 523.xalanbmk teve uma fração relevante do stream de instruções atendida pelo loop buffer, mas a pontuação ficou em 9,48 na BIOS nova e 9,44 na BIOS antiga, dentro da margem de erro
- O 544.nab recebeu quase um quarto dos micro-ops pelo loop buffer, mas marcou 11,7 na BIOS nova com o loop buffer desligado, contra 11,5 antes, um aumento de 1,7%
- Esse aumento pode ser apenas variação entre execuções
- Nos contadores de desempenho da BIOS nova, o op cache assume o papel do loop buffer e atende uma parte maior do stream de instruções
- Em 507.cactuBSSN, a cobertura do op cache cai um pouco e aparece um padrão em que os decodificadores fornecem cerca de um quarto de todos os micro-ops
- Contadores de desempenho servem mais para mostrar tendências gerais do que medições 100% precisas
- O dispatch do frontend é um evento especulativo, então também pode incluir instruções buscadas incorretamente após branches mal previstos
Possível economia de energia e atividade do frontend
- O objetivo principal do loop buffer não é aumentar desempenho, e sim desligar oportunisticamente boa parte do frontend, incluindo o op cache
- Os recursos de monitoramento de desempenho do Zen 4 incluem count mask, que permite contar ciclos em que um evento ultrapassa determinado limiar
- Com o limiar em 1, é possível estimar em quantos ciclos cada fonte de micro-ops realmente forneceu micro-ops
- Isso permite avaliar com que frequência o frontend pode ser desligado quando o loop buffer está ativo
- No SPEC CPU2017, a frequência de ativação de cada fonte combina razoavelmente bem com a proporção de micro-ops entregue por ela
- Em algumas cargas, há também muitos ciclos em que o frontend não fornece nada
- 502.gcc e 520.omnetpp ficam bastante limitados pela latência de memória do backend
- Se o mecanismo de execução fora de ordem não consegue manter instruções suficientes in flight para esconder a latência, o frontend não consegue mandar mais trabalho ao backend e fica ocioso
- No suite de ponto flutuante, 544.nab e 508.namd usam o loop buffer durante uma parcela considerável dos ciclos do core
- O 508.namd é uma carga de alto IPC com média de 3,64 IPC, então exige bastante throughput do frontend
- Por ser favorável ao loop buffer, há oportunidade de desligar o op cache e economizar energia
- Quando o loop buffer é desligado, o op cache precisa alimentar o core por mais ciclos
- Em 523.xalanbmk, sem loop buffer o op cache precisa ficar ativo por mais 12% dos ciclos do core
- 548.exchange2 é uma carga de alto IPC com média de 4,31 IPC, mas quase não usa o loop buffer mesmo quando ele está ligado, e o op cache fica ativo em mais de 85% dos ciclos do core
- Em 508.namd, a taxa de atividade do op cache sobe de 56,67% com loop buffer ativo para 75,1% com ele desativado
- Um loop buffer de 144 entradas é pequeno demais para cobrir grande parte do stream de instruções
- Ele provavelmente só terá efeito perceptível quando o programa passa bastante tempo em pequenos loops e não está limitado pelo throughput ou pela latência do backend
Observações em Cyberpunk 2077
- O benchmark embutido de Cyberpunk 2077 foi usado para verificar o impacto da desativação do loop buffer no desempenho em jogos
- Para melhorar a consistência, o Core Performance Boost foi desativado em um Ryzen 9 7950X3D e todos os núcleos foram limitados a 4.2GHz
- Foi definido o bit 25 do Hardware Configuration register MSR 0xC0010015
- A RX 6900 XT foi limitada a 2GHz
- As configurações do benchmark foram 1080p, preset médio, sem upscaling
- Ao fixar o jogo no die com VCache, desativar o loop buffer quase não afetou o desempenho
- Ao fixá-lo no die sem VCache, foi observada perda de 5% de desempenho com o loop buffer desativado, mas a causa não foi identificada
- O benchmark foi reexecutado cerca de seis vezes
- Em média, Cyberpunk 2077 teve cerca de 22% do stream de instruções atendido pelo loop buffer, tornando-se mais favorável a ele do que o esperado
- Após a desativação, a participação do op cache no fornecimento de micro-ops subiu de 62% para 82%
- O jogo não é uma carga de alto IPC, com média de 0,89 IPC com o loop buffer desativado e 1,02 IPC com ele ativo
- A largura de banda do frontend não é uma grande preocupação
- É possível que esteja limitado pelo backend ou por atrasos do branch predictor
- Ao rodar no die com VCache, os contadores de desempenho mostraram média de 1,25 IPC com o loop buffer ativo e 1,07 IPC com ele desativado
- Também foi observada uma pequena queda de desempenho na BIOS nova
- É possível que o sistema tenha ficado mais próximo de um gargalo do lado da GPU em torno de 155 FPS
Incerteza nos resultados do contador de energia do core
- Para verificar se a execução via loop buffer melhora a eficiência energética, também foi observado o contador de energia do core do Zen 4
- O benchmark de largura de banda de instruções foi modificado para não usar CALL/RET durante a região de teste
- Isso porque, com CALL/RET, o Zen 4 não usa o loop buffer
- O teste foi fixado em um único core, e a potência média foi calculada lendo o Core Energy Status MSR antes e depois do salto para o array de teste
- O Core Performance Boost foi desativado porque as leituras de energia variavam muito
- Na BIOS antiga, o Core Energy Status MSR indicava consumo médio de 6W ao buscar NOPs do op cache, e consumo bem menor ao buscá-los do loop buffer
- Mesmo ao aumentar o tamanho do array de teste até 128KB, cabendo no L2 e reduzindo a cobertura do op cache para menos de 1%, a potência média do core aparecia como 1,5W
- Esse resultado não combina com uma situação em que deveria haver mais uso dos decodificadores e do caminho de fetch do L2
- Na BIOS nova, o teste com op cache mostrou média de 1,68W, e o teste em que os decodificadores eram alimentados principalmente a partir do L2 mostrou quase o mesmo consumo
- Os recursos de monitoramento de energia da AMD podem ser modelagem de energia, e não medição direta
- O método de modelagem pode ter mudado entre versões de BIOS, ou o modelo pode não estar adequado
- Não houve validação adicional por falta de hardware para medir diretamente em conectores como o 12V EPS
Motivo da desativação e visão para desenvolvedores
- Não se sabe por que a AMD desativou o loop buffer do Zen 4
- Às vezes recursos de CPU são desativados por causa de bugs de hardware
- Houve o caso do LSD, o loop buffer do Intel Skylake, desativado por causa de um bug relacionado a acesso parcial a registradores em loops curtos com duas threads SMT ativas
- O Zen 4 foi a primeira tentativa da AMD de colocar um loop buffer em uma CPU de alto desempenho, e validar uma primeira implementação é difícil
- É possível que a AMD tenha encontrado internamente algum bug não exposto publicamente e desativado o loop buffer por precaução
- O impacto em desempenho parece quase nulo ou muito pequeno, porque a largura de banda do op cache é suficiente
- O impacto em energia é desconhecido, mas pode ser pequeno e difícil de medir
- A AMD quase não documentou nem divulgou o loop buffer além de uma linha no Processor Programming Reference
- Isso contrasta com a Intel, que costuma documentar seu loop buffer e recomendá-lo em guias de otimização para que desenvolvedores o aproveitem
- O loop buffer do Zen 4 é um recurso limitado e menos útil que o op cache por causa da baixa capacidade e da limitação com CALL/RET
- Se alguém quiser otimizar pensando no loop buffer do Zen 4 em BIOS antigas, pode considerar as seguintes condições
- Manter loops com menos de 144 micro-ops
- Considerar metade disso quando duas threads compartilham o mesmo núcleo físico
- Avaliar inline para funções chamadas dentro de loops pequenos, evitando CALL/RET
- Mesmo com essas otimizações, a chance é grande de não haver benefício prático
1 comentários
Opiniões no Hacker News
Fico especulando se esse recurso não foi desativado como uma tentativa de impedir uma vulnerabilidade de hardware ainda não divulgada
Não é absurdo imaginar que a AMD tenha encontrado internamente um bug que ninguém havia esbarrado antes e, por excesso de cautela, tenha desligado o buffer de loop. Neste ponto do ciclo de vida do core, não consigo pensar em muitos outros motivos para a AMD mexer no front-end do Zen 4
Pessoalmente, isso me cheira a mitigação por microcódigo, mas, claro, é preciso esperar por um CVE
Se a vulnerabilidade não for divulgada, as partes afetadas não têm como começar a responder, exceto por pura paranoia. Divulgar uma vulnerabilidade também é uma forma de transferir a responsabilidade para o usuário final. É aquela lógica de “se você não atualizou, não reclame”. Raramente a divulgação leva à responsabilização pelo produto, e não me lembro de isso ter acontecido nem com Meltdown ou Spectre. Por isso, eu não concluiria que a AMD está escondendo de propósito
O texto parece sugerir que o buffer de loop não traz ganho de desempenho nem de energia
Nesse caso, pode ser o clássico caso de “uma equipe de engenharia passou meses criando um recurso novo e reluzente, ele não trouxe ganho real, mas alguém o lançou mesmo assim para salvar as aparências”. Já vi em equipes de software a ideia de reescrever uma base de código para eliminar inchaço legado e melhorar desempenho, só para no fim o número de linhas aumentar e o desempenho piorar. Em ambos os casos, não deveriam ter lançado
É difícil acreditar que a equipe de engenharia da AMD fosse tão sem critério a ponto de gastar área e energia com um recurso de hardware sem valor algum; neste caso, eu tenderia a achar mais provável que o Chips 'n Cheese não tenha conseguido medir o impacto
É muito frustrante, mas ninguém quer gastar tempo fazendo investigação prévia. Empurrar um projeto novo costuma agradar mais a alta gestão e gerar menos perguntas
O parágrafo mais interessante do texto é este: a melhor maneira de enxergar o buffer de loop do Zen 4 é como um sinal de que a AMD tem capacidade sobrando para seus engenheiros tentarem coisas
Talvez desta vez não tenha dado resultado, mas deixar engenheiros experimentarem com recursos de baixo risco e baixo impacto é uma boa forma de construir confiança. Espero ver mais dessa confiança daqui para frente
Sobre o trecho “Curiosamente, ao fixar no die non-VCache, desativar o buffer de loop reduz o desempenho em jogos em 5%. Não sei por quê”, fico pensando se medições mais refinadas de energia permitiriam saber se isso tem a ver com orçamento térmico/de energia
Esse recurso também parece ter sido pensado para economizar energia
No meu chip non-X3D, a maioria dos cores do CCD0 chega a 5,6–5,75 GHz, mas os cores do CCD1 param em 5,4–5,5 GHz. Os chips V-Cache do Zen 4 têm uma penalidade grande de clock, mas o cache compensa mais do que isso. Seria preciso ver se testaram o CCD1 do mesmo chip com o recurso ligado e desligado, e se tentaram isolar outras mudanças, como correções de segurança; no texto, eles próprios admitem que “não”. Para fazer direito, seria necessário encontrar um jeito de desligar apenas esse recurso em um BIOS em que ele esteja habilitado e testar os dois cenários no mesmo chip; mesmo assim, por causa de outras condições de ramificação, o resultado talvez não fosse exato. Um perfil de desempenho completo melhoraria a precisão, mas provavelmente só engenheiros da AMD conseguiriam fazer isso
Parece ter sido pequeno demais para fazer diferença real, e só tinha importância em situações muito específicas. Se o tornassem maior, o custo de implementação provavelmente seria alto demais em relação ao benefício
Ainda assim, haveria uma pequena regressão em algumas cargas de trabalho, mas a AMD também tem feito pequenas melhorias de desempenho depois do lançamento. No Zen 4, isso deveria ter sido simplesmente uma opção no BIOS. O fato de aparentemente não terem feito isso sugere a possibilidade de bug ou problema de segurança
Como anedota, uma das poucas diferenças entre o 68000 de 1979 e o 68010 de 1982 era o “loop mode”, ou seja, a adição de um buffer de loop de 6 bytes
Consistia em executar duas CPUs defasadas em um ciclo e injetar uma interrupção recuperável na segunda CPU. Ainda assim, se você quisesse uma CPU com MMU, conjunto de instruções de 32 bits e barramento de endereços de 24 bits, parece que era mais barato do que as alternativas da época. Devem ter sido tempos realmente difíceis
Cabem 4 instruções em uma palavra de 18 bits, e um opcode decrementa o contador de loop e então volta para o início da palavra. Nesses casos, pode executar bem mais rápido
Uma delas tinha de ser a instrução de loop (DBcc), então o corpo do loop precisava ser uma única instrução. Na prática, quase a única coisa que podia ficar mais rápida era algo como um memcpy não otimizado
É interessante que, no Cortex-A15, isso seja um recurso central de projeto. Fico curioso se há números sobre o efeito em outros chips
Em dispositivos com vida útil de projeto mais longa, como consoles, parece que ao menos poderia ser usado como alvo de otimização
Afinal, a ideia do RISC é que buscar e decodificar instruções seja muito mais fácil, ou quase trivial
Tenho um 7950X3D, para o qual fiz upgrade a partir de um Skylake 6700K. Parece que, inconscientemente, sou atraído por chips em que o buffer de loop por hardware foi desativado por software
Artigo interessante, mas não sei quanto espaço o buffer de loop ocupa no die
Fico pensando se, caso ele seja removido em chips futuros, esse espaço poderia ser usado para algo mais útil, como um cache L2 maior
Em teoria, um buffer de loop pode economizar energia ou aumentar o desempenho em loops apertados. Na prática, parece não conseguir fazer nenhum dos dois, e a AMD o removeu completamente no Zen 5
Se isso estiver certo, faz sentido, e o custo em área seria só alguma lógica de controle extra. A parte mais cara provavelmente é detectar o loop em primeiro lugar, mas ainda deve ser bem pequena em comparação com o tamanho da fila
A análise da seção “energia” parece não ter sido dividida pelo número de instruções executadas por segundo
Para ver os benefícios desse buffer de loop, é quase certo que seria preciso olhar para energia por instrução, não energia por segundo, ou seja, potência (watts)
Até a ordem e o conteúdo da RAM podem mudar tudo. Dá para executar centenas de vezes com o recurso ligado e desligado para isolar um pouco, mas isso consome muito tempo e ainda assim não é 100% exato. Só desligar o recurso já pode fazer o código seguir um ramo diferente e mudar todo o layout. Não conheço este problema específico, mas já vi casos em que, ao desligar um recurso, a carga se deslocava das unidades inteiras para a FPU ou GPU, ou em que 5 instruções desapareciam, mas 2 eram adicionadas