Por que o aumento da profundidade do pipeline nem sempre significa aumento da taxa de transferência?

StackOverflow https://stackoverflow.com/questions/2597189

  •  25-09-2019
  •  | 
  •  

Pergunta

Talvez isso seja mais uma pergunta de discussão, mas eu pensei que o StackOverflow poderia ser o lugar certo para fazer. Estou estudando o conceito de pipelining de instrução. Fui ensinado que a taxa de transferência de instrução de um pipeline é aumentada quando o número de estágios de pipeline é aumentado, mas, em alguns casos, a taxa de transferência pode não mudar. Em que condições, isso acontece? Estou pensando que parar e ramificar pode ser a resposta para a pergunta, mas me pergunto se estou perdendo algo crucial.

Foi útil?

Solução

O todo pode ser paralisado por outras instruções ao aguardar um resultado ou em cache erros. A pipelining não garante que as operações sejam totalmente independentes. Aqui está uma ótima apresentação sobre os meandros da arquitetura X86 Intel/AMD: http://www.infoq.com/presentations/click-crash-course-modern-hardware

Ele explica coisas como essa em detalhes e abrange algumas soluções sobre como melhorar ainda mais a taxa de transferência e ocultar a latência. JustJeff mencionou a execução fora de ordem para um, e você tem registros de sombra não expostos pelo modelo do programador (mais de 8 registros em x86) e você também tem previsão de filial.

Outras dicas

Concordou. Os maiores problemas são as barracas (aguardando resultados de instruções anteriores) e previsão incorreta da filial. Se o seu pipeline tiver 20 etapas de profundidade e você está esperando os resultados de uma condição ou operação, esperará mais do que se o seu pipeline tivesse apenas 5 etapas. Se você prever o ramo errado, precisará liberar 20 instruções do pipeline, em oposição a 5.

Eu acho que, presumivelmente, você pode ter um pipeline profundo, onde vários estágios estão tentando acessar o mesmo hardware (ALU etc.), o que causaria um sucesso de desempenho, embora esperançosamente você lançar unidades adicionais suficientes para apoiar cada estágio.

O paralelismo no nível de instrução tem retornos decrescentes. Em particular, as dependências de dados entre as instruções determinam o possível paralelismo.

Considere o caso de leitura após gravação (conhecido como RAW em livros didáticos).

Na sintaxe em que o primeiro operando obtém o resultado, considere este exemplo.

10: add r1, r2, r3
20: add r1, r1, r1

O resultado da linha 10 deve ser conhecido no momento em que o cálculo da linha 10 começa. O encaminhamento de dados mitiga esse problema, mas ... apenas ao ponto em que os dados são conhecidos.

Eu também pensaria que o aumento da pipelinização além da quantidade de tempo que a instrução mais longa de uma série levaria para executar não causaria um aumento no desempenho. Eu acho que parar e ramificar são as questões fundamentais.

Definitivamente, as barracas/bolhas em dutos longos causam uma enorme perda na taxa de transferência. E, é claro, quanto mais tempo o pipeline, mais ciclos de relógio são desperdiçados.

Tentei por um longo tempo pensar em outros cenários em que oleodutos mais longos poderiam causar uma perda de desempenho, mas tudo volta às barracas. (E número de unidades de execução e esquemas de emissão, mas esses não têm muito a ver com a duração do pipeline.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top