AOC – Pipeline I

7 maio

AOC?

Para evitar grandes títulos, ao decorrer dos posts, vou procurar utilizar siglas em vez dos nomes completos das disciplinas, mas os escrevendo por extenso no cabeçalho dos posts.

Então, começando:

Arquitetura e Organização de Computadores

Pipeline

Então, se você é da área, provavelmente já ouviu falar em Pipeline. Na aula de hoje aprendi o que é o Pipeline, conheci seus hazards e suas estratégias te otimização.

Em poucas palavras:

  • O que é? Pipeline é a implementação de uma técnica para otimizar o processador .
  • Como? O Pipeline é baseado em cliclos de clock para processar uma instrução. Cada instrução é quebrada em um número N de passos cada um guardando um valor que será usado como input no próximo passo. No Pipeline, essas instruções são sobrepostas de modo que a cada ciclo do clock, um passo de cada instrução seja executado (Fig. 1), evitando deixar componentes do processador ociosos. A performance do processador é aumentada proporcionalmente ao número de passos em que as instruções são quebradas.

Fig. 1 - Cada instrução possui 6 passos que são sobrepostos no Pipeline e executados a cada ciclo de clock de modo que a partir do 5o ciclo, a cada novo ciclo uma instrução é terminada.


Com mais detalhes:

Antes, vale a pena lembrar que:

Uma instrução em linguagem de montagem (Assembly) é formada por campos que guardam os dados necessários para a execução da instrução, geralmente apresentados como:

  • Opcode (Código de Operação) – Código que em Assembly é representado por um mnemônico, ou abreviações como ADD, MOV, STOR, etc. e indica a operação que vai ser executada, tanto quanto o modo de endereçamento de operandos utilizado.
  • N Campos de endereço – O número de campos de endereço dos operandos varia de acordo com a necessidade da operação. Geralmente de 0 a 3 operandos sendo eles o operando fonte, operando destino e dependendo da arquitetura do conjunto de instruções, uma referência à próxima instrução.
E que a CPU possui componentes internos como Buscador de Instruções, Decodificador de Instruções, Conjunto de Registradores e ULA(Unidade Lógica e Aritmética) para citar os mais comuns, com isso em mente podemos dizer que quando uma instrução é apresentada ao processador, ele ativa cada um desses componentes internos para realizar uma parte da execução dessa instrução. Esse processo é demonstrado na Fig. 2 abaixo:

Fig. 2 - Diagrama do Ciclo de Instrução

De acordo com a Fig. 2, vemos que para cada passo da execução de uma instrução apenas um componente da CPU é utilizado, deixando todos os outros componentes ociosos, e isso é um grande desperdício de processador. Para resolver esse problema, o Pipeline foi introduzido na organização dos processadores.

Como visto na Fig. 1, o Pipeline é dividido em estágios de acordo com o ciclo de instrução. O número de estágios varia dependendo do tipo de processador, em nosso caso são 6:

  • FI (Fetch Instruction) – Busca a próxima instrução e a armazena em um buffer.
  • DI (Decodificar Instrução) – Determina o opcode e os operandos que serão usados.
  • CO (Calcular Operandos) –  Calcula o endereço dos operandos de origem baseado na forma de endereçamento usada na instrução.
  • FO (Fetch Operands) – Busca cada operando da memória, de uma E/S (I/O) ou de um registrador.
  • EI – Executa a operação indicada na instrução.
  • WO (Write Operand) – Escreve o resultado na memória.
Desse modo, é possível sobrepor as instruções permitindo que a cada ciclo de clock o processador utilize todos seus componentes para executar cada estágio de diversas instruções ao mesmo tempo. Aumentando a performance do processador de modo que:
  • No estágio 1, a instrução é buscada e armazenada. Já no estágio 2 o Decodificador é ativado para interpretar a instrução, enquanto o estágio 1 está buscando uma nova instrução. Quando os estágios 1 e 2 terminam, o estágio 2 passa para o estágio 3 e começa a calcular os operandos, o estágio 1 passa para o estágio 2 e começa a decodificar a instrução recém adquirida e o estágio 1 busca uma nova instrução. Mantendo sempre os componentes responsáveis por cada estágio trabalhando. Isso monta a escada de execução mostrada na Fig. 1.
Agora que já entendemos o que é o Pipeline de instruções, algumas perguntas são feitas:
  1. Se no pipeline várias instruções são executadas ao mesmo tempo, como o processador sabe quais vão ser essas próximas instruções?
  • De modo geral, o pipeline carrega sempre a próxima instrução na sequência. Veja o trecho de código abaixo.
MOV AL, 1h             ; Instrução 1
MOV EAX,  [EBX]  ; Instrução 2
SUB AH, AL             ; Instrução 3
Cada instrução é carregada no pipeline na ordem de sequência. A instrução 1, depois a 2, depois a 3. E isso funciona muito bem, se assumirmos que cada instrução sempre vai passar por todos os 6 estágios do pipeline, o que nem sempre acontece. Uma instrução de LOAD, por exemplo, não tem resultado e não precisa do último estágio WO (para escrever um resultado na memória). Além disso, supõe-se que todos estágios podem ser executados em paralelo e que não haverão conflitos de memória. De todos os possíveis problemas que podem aparecer no pipeline, se destaca um: desvios condicionais.
Como o pipeline busca a próxima instrução n+1 antes que a instrução anterior n termine de executar, o que acontece quando a instrução n é um desvio condicional?
MOV AX, 10h      ; Instrução 1
CMP AX, BX         ; Instrução 2
    JAE  9f                  ; Instrução 3
SUB AX, 5h           ; Instrução 4
9: ADD SP, 8          ; Instrução 15
No trecho de código acima temos um exemplo de desvio condicional, onde se a comparação na instrução 3 for verdadeira, o programa é desviado para a instrução 15, como demonstrado na Fig. 3.

Fig. 3 - Desvio Condicional e Penalidade de Desempenho

Em uma situação como essa, no início na execução da instrução 3, o processador não tem nenhuma maneira de saber se o desvio será tomado ou não, então as instruções da sequência são executadas e ao fim da execução da instrução 3, se o desvio for tomado, todas as instruções entre 3 e 15 são removidas do pipeline e nenhuma instrução é executada entre os tempos t8 e t12. Isso é chamado de penalidade de desempenho.

Outras situações que resultam em perda de desempenho do pipeline ocorrem quando o pipeline ou alguma parte dele, precisa parar porque alguma condição não permite que ele continue. Essas ‘paradas’ são chamadas de bolhas e essas situações que causam de perda de desempenho no pipeline, o impedem de prosseguir ou o fazem computar incorretamente são chamadas de Hazards do Pipeline e são divididos em três tipos que serão detalhados no próximo post de AOC. Os três tipos de hazards são: recurso, dados e controle.

Até a próxima!

Deixe um comentário