Perigo (arquitetura de computador) - Hazard (computer architecture)

No domínio da unidade central de processamento (CPU) de design , os perigos são problemas com o encanamento de instrução na CPU microarquiteturas quando a próxima instrução não podem ser executadas na seguinte ciclo de clock, e pode potencialmente levar a resultados incorretos computação. Três tipos comuns de riscos são riscos de dados, riscos estruturais e riscos de controle (riscos de ramificação).

Existem vários métodos usados ​​para lidar com os perigos, incluindo paralisações de pipeline / borbulhamento de pipeline, encaminhamento de operando e, no caso de execução fora de ordem , o método de scoreboard e o algoritmo Tomasulo .

Fundo

As instruções em um processador em pipeline são executadas em vários estágios, de forma que, a qualquer momento, várias instruções sejam processadas nos vários estágios do pipeline, como buscar e executar. Existem muitas microarquiteturas de pipeline de instruções diferentes e as instruções podem ser executadas fora de ordem . Um perigo ocorre quando duas ou mais dessas instruções simultâneas (possivelmente fora de ordem) entram em conflito.

Tipos

Riscos de dados

Os riscos de dados ocorrem quando as instruções que exibem dependência de dados modificam os dados em diferentes estágios de um pipeline. Ignorar riscos potenciais de dados pode resultar em condições de corrida (também chamados de riscos de corrida). Existem três situações em que pode ocorrer um risco de dados:

  1. leitura após gravação (RAW), uma verdadeira dependência
  2. escrever após ler (WAR), um anti-dependência
  3. write after write (WAW), uma dependência de saída

Ler depois de ler (RAR) não é um caso de perigo.

Considere duas instruções i1 e i2 , com i1 ocorrendo antes de i2 na ordem do programa.

Ler depois de escrever (RAW)

( i2 tenta ler uma fonte antes de i1 gravar nela) Um perigo de dados de leitura após gravação (RAW) se refere a uma situação em que uma instrução se refere a um resultado que ainda não foi calculado ou recuperado. Isso pode ocorrer porque, embora uma instrução seja executada após uma instrução anterior, a instrução anterior foi processada apenas parcialmente por meio do pipeline.

Exemplo

Por exemplo:

i1. R2 <- R5 + R3
i2. R4 <- R2 + R3

A primeira instrução está calculando um valor a ser salvo no registro R2 , e a segunda vai usar esse valor para calcular um resultado para o registro R4 . No entanto, em um pipeline , quando operandos são buscados para a 2ª operação, os resultados da primeira ainda não foram salvos e, portanto, ocorre uma dependência de dados.

Uma dependência de dados ocorre com a instrução i2 , pois é dependente da conclusão da instrução i1 .

Escreva após a leitura (WAR)

( i2 tenta gravar um destino antes de ser lido por i1 ) Um perigo de dados de gravação após leitura (WAR) representa um problema com a execução simultânea.

Exemplo

Por exemplo:

i1. R4 <- R1 + R5
i2. R5 <- R1 + R2

Em qualquer situação com uma chance de que i2 possa terminar antes de i1 (ou seja, com execução simultânea), deve-se garantir que o resultado do registro R5 não seja armazenado antes que i1 tenha a chance de buscar os operandos.

Write after write (WAW)

( i2 tenta escrever um operando antes que ele seja escrito por i1 ) Um perigo de gravação após gravação (WAW) de dados pode ocorrer em um ambiente de execução simultânea .

Exemplo

Por exemplo:

i1. R2 <- R4 + R7
i2. R2 <- R1 + R3

O write-back (WB) de i2 deve ser atrasado até que i1 termine de ser executado.

Riscos estruturais

Um perigo estrutural ocorre quando duas (ou mais) instruções que já estão em pipeline precisam do mesmo recurso. O resultado é que a instrução deve ser executada em série em vez de paralela para uma parte do pipeline. Riscos estruturais são às vezes chamados de riscos de recursos.

Exemplo: Uma situação em que várias instruções estão prontas para entrar na fase de execução da instrução e há uma única ALU (Unidade Lógica Aritmética). Uma solução para esse risco de recursos é aumentar os recursos disponíveis, como ter várias portas na memória principal e várias unidades ALU (unidade lógica aritmética).

Riscos de controle (riscos de ramificação ou riscos de instrução)

O risco de controle ocorre quando o pipeline toma decisões erradas sobre a previsão do ramal e, portanto, traz instruções para o pipeline que devem ser posteriormente descartadas. O termo perigo de ramificação também se refere a um perigo de controle.

Eliminando perigos

Genérico

Pipeline borbulhando

Fazer borbulhar o pipeline , também denominado quebra do pipeline ou paralisação do pipeline , é um método para evitar riscos de dados, estruturais e de ramificação. Conforme as instruções são buscadas, a lógica de controle determina se um perigo pode / irá ocorrer. Se isso for verdade, a lógica de controle não insere nenhuma operação ( NOP s) no pipeline. Assim, antes de a próxima instrução (que causaria o perigo) ser executada, a anterior terá tido tempo suficiente para terminar e prevenir o perigo. Se o número de NOP s for igual ao número de estágios no pipeline, o processador foi eliminado de todas as instruções e pode continuar livre de perigos. Todas as formas de travamento apresentam um atraso antes que o processador possa retomar a execução.

A liberação do pipeline ocorre quando uma instrução de ramificação salta para um novo local de memória, invalidando todos os estágios anteriores do pipeline. Esses estágios anteriores são limpos, permitindo que o pipeline continue na nova instrução indicada pelo branch.

Riscos de dados

Existem várias soluções e algoritmos principais usados ​​para resolver os riscos de dados:

  • inserir uma bolha de pipeline sempre que uma dependência de leitura após gravação (RAW) for encontrada, garantido para aumentar a latência, ou
  • use a execução fora de ordem para evitar potencialmente a necessidade de bolhas de pipeline
  • use encaminhamento de operando para usar dados de estágios posteriores no pipeline

No caso de execução fora de ordem , o algoritmo usado pode ser:

A tarefa de remover dependências de dados pode ser delegada ao compilador, que pode preencher um número apropriado de instruções NOP entre as instruções dependentes para garantir a operação correta, ou reordenar as instruções quando possível.

Encaminhamento de operando

Exemplos

Nos exemplos a seguir, os valores calculados estão em negrito , enquanto os números de registro não.

Por exemplo, para escrever o valor 3 no registrador 1, (que já contém um 6), e então adicionar 7 ao registrador 1 e armazenar o resultado no registrador 2, ou seja:

i0: R1 = 6
i1: R1 = 3
i2: R2 = R1 + 7 = 10

Após a execução, o registro 2 deve conter o valor 10 . No entanto, se i1 (gravar 3 no registrador 1) não sair totalmente do pipeline antes de i2 começar a ser executado, significa que R1 não contém o valor 3 quando i2 executa sua adição. Nesse caso, i2 adiciona 7 ao valor antigo do registro 1 ( 6 ) e, portanto, o registro 2 contém 13 , ou seja:

i0: R1 = 6
i2: R2 = R1 + 7 = 13
i1: R1 = 3

Este erro ocorre porque i2 lê o Registro 1 antes de i1 ter confirmado / armazenado o resultado de sua operação de gravação no Registro 1. Portanto, quando i2 está lendo o conteúdo do Registro 1, o registro 1 ainda contém 6 , não 3 .

O encaminhamento (descrito abaixo) ajuda a corrigir esses erros, dependendo do fato de que a saída de i1 (que é 3 ) pode ser usada por instruções subsequentes antes que o valor 3 seja confirmado / armazenado no Registro 1.

O encaminhamento aplicado ao exemplo significa que não há espera para confirmar / armazenar a saída de i1 no Registrador 1 (neste exemplo, a saída é 3 ) antes de tornar essa saída disponível para a instrução subsequente (neste caso, i2). O efeito é que i2 usa o valor correto (o mais recente) do Registro 1: o commit / store foi feito imediatamente e não foi pipeline.

Com o encaminhamento habilitado, o estágio de decodificação / execução de instrução (ID / EX) do pipeline agora tem duas entradas: o valor lido do registro especificado (neste exemplo, o valor 6 do registro 1) e o novo valor do registro 1 (neste exemplo, este valor é 3 ), que é enviado do próximo estágio Execução de Instrução / Acesso à Memória (EX / MEM). A lógica de controle adicionada é usada para determinar qual entrada usar.

Riscos de controle (riscos de ramos)

Para evitar riscos de controle, as microarquitetura podem:

  • inserir uma bolha de pipeline (discutido acima), garantido para aumentar a latência , ou
  • usar a previsão de ramificação e essencialmente fazer suposições informadas sobre quais instruções inserir, caso em que uma bolha de pipeline só será necessária no caso de uma previsão incorreta

No caso de um ramal causar uma bolha no oleoduto após instruções incorretas terem entrado no oleoduto, deve-se tomar cuidado para evitar que qualquer uma das instruções carregadas incorretamente tenha qualquer efeito no estado do processador, excluindo o desperdício de energia processando-os antes de ser descoberto que carregado incorretamente.

Outras técnicas

A latência da memória é outro fator que os designers devem atender, porque o atraso pode reduzir o desempenho. Diferentes tipos de memória têm diferentes tempos de acesso à memória. Assim, ao escolher um tipo adequado de memória, os designers podem melhorar o desempenho do caminho de dados em pipeline.

Veja também

Referências

Em geral

links externos