Organização de Computadores Antônio Borges / Gabriel P. Silva 6

Propaganda
Organização de Computadores
Antônio Borges / Gabriel P. Silva
6. Pipeline
“A quinta parte de um enxame pousou na flor de Kadamba, a terça
parte numa flor de Silinda, o triplo da diferença entre estes dois números voa sobre uma flor de Krutaja, e uma abelha adeja sozinha,
no ar, atraída pelo perfume de um jasmim e de um pandnus. Dizme, bela menina, qual o número de abelhas”
Malba Tahan
O Homem que Calculava
6.1. Introdução
O pipeline é uma técnica de implementação de processadores que permite a sobreposição temporal das diversas fases de execução das instruções. A execução de uma instrução é dividida em
várias etapas ou estágios. Assim, o processador inicia a execução da próxima instrução logo que
a execução do primeiro estágio da instrução atual terminar, ao invés de esperar o término da execução de toda a instrução.
Embora o tempo gasto para completar cada instrução individualmente não seja reduzido, o uso da
técnica de pipeline aumenta o número de instruções executadas simultaneamente e a taxa de
instruções iniciadas e terminadas por unidade de tempo.
Por exemplo, a fabricação de um carro completo leva, por hipótese, seis horas para ser
terminada. Ao final de um dia, em três turnos de 8 horas, uma fábrica com apenas uma linha de
produção terá produzido 4 carros. Contudo, podemos dividir o processo de fabricação em várias
etapas, como a seguir:
–
–
–
–
Montagem do Chassi
Colocação do Motor
Montagem da Carroceria
Colocação de Bancos e Acessórios
Supondo-se que cada uma dessas etapas leve 90 minutos para ser realizada, um carro
continuará levando 6 horas para ser fabricado. Entretanto, podemos iniciar a fabricação de um
carro novo a cada 90 minutos, até que tenhamos 4 carros sendo fabricados simultaneamente, um
em cada etapa do “pipeline”. Depois das primeiras 6 horas, teremos um carro sendo produzido a
cada 90 minutos. Ao final de um dia, em três turnos de 8 horas, uma fábrica com apenas uma linha de produção terá fabricado 16 carros.
6.2. O Pipeline do DLX
Em nosso estudo estaremos considerando um modelo de processador baseado no DLX. È uma
arquitetura simples, onde todas as instruções possuem tamanho fixo (32 bits); apenas as instruções de LOAD e STORE fazem acesso à memória; existem 32 registradores inteiros (32 bits) de
uso geral e um registrador especial, o apontador de instruções (PC), também de 32 bits, que contém o endereço da próxima instrução a ser buscada na memória.
Vamos propor a divisão da execução de cada uma das instruções no nosso processador
em 5 estágios:
−
−
Busca (B)
Decodificação (D)
Organização de Computadores
−
−
−
Antônio Borges / Gabriel P. Silva
Execução (E)
Memória (M)
Escrita (W)
Busca da
Instrução
Decodificação
Execução
Memória
Escrita do
Resultado
Figura 9 – Exemplo de pipeline com 5 estágios
O estágio de Busca (B) utiliza o endereço armazenado no Apontador de Instruções (PC) para a
busca da instrução na memória. Assim que a instrução for carregada nos registradores internos do
processador, o valor do PC é atualizado para apontar para a próxima instrução a ser buscada na
memória.
O estágio de Decodificação (D) realiza a decodificação da instrução, verifica se tem operandos,
quantos são e faz a leitura dos valores do banco de registradores.
O estágio de Execução (E) é responsável pela execução das operações aritméticas e lógicas definidas pela instrução. Neste estágio também é calculado o endereço de memória dos operandos
das instruções de LOAD e STORE e o endereço-alvo para as instruções de desvio.
No estágio de Memória (M) é feito o acesso propriamente dito (leitura ou escrita) aos operandos
que estão em memória. O endereço utilizado é aquele calculado no estágio de execução. Apenas
as instruções de LOAD e STORE realizam alguma tarefa útil neste estágio.
O resultado da execução das instruções, se houver, é escrito no banco de registradores no estágio de Escrita (W). Para que esito possa ser feito sem conflito, o banco de registradores permite a
leitura e a escrita simultânea de operandos. Se houver a leitura e a escrita simulatêneas de um
mesmo registrador, o banco de registradores retorna o novo valor que está sendo escrito.
6.3. Relógio
O relógio é um sinal elétrico periódico que cadencia todas as operações no processador. A passagem de uma instrução e seus resultados de um estágio para outro no pipeline do processador
também é controlada pelo relógio e se dá normalmente ao final do seu ciclo.
Relógio
Ciclo
Organização de Computadores
Antônio Borges / Gabriel P. Silva
Figura 10 – Relógio
O relógio, por ser periódico, possui uma freqüência e tempo de ciclo bem definidos. Quanto maior
a freqüência (f), menor o tempo de ciclo (T) do relógio (T = 1/f). Nos processadores modernos a
freqüência é expressa em GHz e o tempo de ciclo de relógio em ns (10-9 s) ou ps (10-12 s).
O tempo do ciclo do relógio do processador deve ser igual ao tempo de execução do estágio
mais lento do “pipeline”. Ou seja, no projeto de um pipeline, a freqüência do relógio é determinada
pelo inverso do tempo de execução do estágio mais lento. O projetista do processador deve dividir
a execução da instrução em estágios com o mesmo tempo de execução, para obter o máximo
desempenho. Uma outra condição para que este desempenho máximo seja alcançado, é que o
pipeline deve ser mantido sempre “cheio”, ou seja, não pode haver estágios sem instruções úteis
em execução.
6.4. Caminho de Dados
Uma instrução para ser executada no pipeline percorre um caminho de dados que corresponde à
divisão em estágios da arquitetura do DLX, conforme a figura abaixo. A execução das instruções
obedece a um fluxo da esquerda para a direita. As únicas exceções ocorrem quando é feita a escrita do resultado no banco de registradores, no estágio de escrita, que utiliza o mesmo recurso do
estágio de decodificação que é o banco de registradores; e na seleção do próximo valor do PC,
que é escolhido entre o PC incrementado de 4 e o endereço do desvio condicional calculado pelo
somador no estágio de execução.
Figura 11 – Diagrama do Pipeline do DLX
Para que possa haver a leitura simultânea de até dois operandos, da instrução que está no estágio de decodificação (D), e a escrita de um resultado, da instrução que está no estágio de escrita
(W), possam ser feitas simultaneamente, o banco de registradores deve possuir duas portas de
leitura e uma de escrita. Cada porta é constituída por uma saída/entrada de 32 bits de dados e um
endereço de 5 bits, que corresponde ao número do registrador que está sendo lido/escrito.
Organização de Computadores
Antônio Borges / Gabriel P. Silva
Para que o controle do pipeline possa ocorrer corretamente, é necessário que cada estágio esteja
isolado do outro por meio de registradores que vão armazenar o resultado das operações de cada
estágio. A própria instrução deve ser enviada de estágio para estágio, para que em cada um deles
as funções apropriadas possam ser executadas. Ao final do pipeline, a instrução é descartada.
6.5. Conflitos no Pipeline
Existem situações em que a próxima instrução não pode ser executada no ciclo de relógio seguinte:
6.5.1.
Conflitos Estruturais
Quando dois ou mais estágios necessitam do mesmo recursos simultaneamente. Por exemplo, pode haver acessos simultâneos à memória sendo feitos tanto pelo estágio de busca de
instrução (B) como pelo estágio de acesso à memória (M).
Busca de
Instrução
Decodificação
Memória
Execução
Memória
Escrita
Resultado
Memória
Figura 12 – Conflitos Estruturais
Soluções possíveis:
A solução normalmente empregada é a duplicação de recursos. No caso do acesso simultâneo à memória pelos estágios de Busca e Memória, a solução usual é o uso de caminhos separados para acesso aos dados e instruções,
normalmente armazenados em memórias caches separadas para dados e instruções. Memórias caches são elementos da hierarquia de memória que possuem cópias dos dados e instruções mais freqüentemente utilizados pelo
processador.
6.5.2.
Conflitos de Controle
Ocorrem devido às instruções de desvio e de chamada de procedimento. Nesse caso, a
próxima instrução a ser executada não estará no endereço de memória subseqüente ao da
instrução atual.
–
Organização de Computadores
Antônio Borges / Gabriel P. Silva
decisão sobre desvio
Tempo
desvio
condicional
Instruções
abandonadas
próxima
instrução
Figura 13 – Desvio Condicional
Por exemplo, o efeito dos desvios condicionais: se o desvio ocorre, o pipeline precisa ser esvaziado, contudo, não se sabe se desvio ocorrerá ou não até o momento em que a instrução de desvio
chegue no estágio de Execução.
Soluções possíveis são:
−
“Desvio Atrasado”: é uma acomodação ao problema, a instrução após o desvio é
sempre executada. Nesse caso cabe ao compilador encontrar instruções que possam ser movidas para depois do desvio. Caso isso não seja possível a posição é
preenchida com uma instrução de “nop”;
−
Predição estática de desvios: o compilador presume que o desvio vai ser tomado ou
não, levando em conta o endereço alvo do desvio, a instrução de alto nível que gerou o desvio, etc. A taxa de acerto para a predição estática costuma ser na ordem
de 80%;
−
Predição dinâmica de desvios: nesse caso o processador possui circuitos que fazem a predição do resultado do desvio condicional no comportamento daquele desvio no passado. As taxas de acerto obtidas com esse método são bastante altas,
chegando até a 97% nos esquemas mais sofisticados
Organização de Computadores
6.5.3.
Antônio Borges / Gabriel P. Silva
Conflito por Dependência de Dados
As instruções dependem de resultados de instruções anteriores, que estão no pipeline e ainda
não foram completadas. Por exemplo, no trecho de código a seguir a instrução sub precisa do
valor de r1 já no estágio de Decodificação, mas a instrução "add" ainda está no estágio de
Execução, e o resultado só será escrito no estágio de Escrita:
add R1, R2, R3
sub R5, R4, R1
Soluções:
–
No caso das dependências verdadeiras, o pipeline precisa ser parado durante certo
número de ciclos. A instrução que precisa do dado fica parada no estágio de decodificação até que o resultado seja atualizado no banco de registradores.
–
O uso de adiantamento dos dados, que é um caminho de dados direto entre a saída da
ALU e sua entrada, é uma solução usualmente empregada, e resolve o problema
quando as instruções dependentes são consecutivas uma à outra no pipeline. Veja a ilustração a seguir:
D
B
M
E
W
Figura 23 - Adiantamento de Dados
Adiantamento
B
D
B
E
D
M
E
W
M
W
Em realidade, há diversos tipos de dependências de dados:
Dependências verdadeiras ou diretas: que são as vistas anteriormente e se constituem
em um problema para os pipelines convencionais.
Dependências falsas: são um problema apenas em pipelines de arquiteturas avançadas, que executam as instruções fora da ordem especificada no código objeto. Podem
ser classificadas em:
–
–
antidependência: a instrução seguinte escreve em um registrador que é lido pela instrução anterior.
dependência de saída: a instrução seguinte escreve no mesmo registrador que
é escrito pela instrução anterior.
Organização de Computadores
Antônio Borges / Gabriel P. Silva
6.6. Tratamento de Exceções nos Pipelines
Uma instrução pode ter problemas durante a sua execução. Por exemplo, uma instrução de multiplicação pode dar “overflow”, ou seja, o resultado pode não caber em 32 bits. Toda vez que uma
instrução não consegue terminar normalmente sua execução, diz-se que ocorreu uma exceção.
O uso do pipeline dificulta o tratamento das exceções, pois precisamos evitar que as instruções
que já estão no pipeline, mas que foram buscadas depois da instrução que causou a exceção,
alterem o estado da máquina, ou seja, que escrevam seus resultados no banco de registradores
ou na memória.
Essas instruções precisam ser anuladas ou descartadas do pipeline, e o apontador de instruções
(PC) deve apontar para a instrução correta, aquela que causou a exceção, no início da rotina do
que irá fazer o tratamento das exceções.
Existe também um problema quando várias exceções ocorrem ao mesmo tempo no pipeline (p.ex.
“overflow” e acesso a um endereço de memória inválido). A solução nesse caso é priorizar as exceções, fazendo o atendimento daquela mais prioritária.
Em máquinas com despacho de várias instruções por ciclo, garantir sempre um estado da máquina consistente pode ser muito complexo em termos de “hardware”. Nesses casos, pode-se utilizar
um modelo de exceções imprecisas, em que a exceção é sempre detectada, mas não se pode
garantir que o estado da máquina não foi alterado.
6.7. Máquinas que Despacham Múltiplas Instruções por Ciclo
6.7.1.
Superescalares
As máquinas superescalares são conhecidas por possuírem mais de um pipeline em paralelo em
sua arquitetura. Desse modo, duas ou mais instruções são buscadas, decodificadas, executadas e
escrevem seus resultados a cada ciclo de máquina.
Claro, isto gera problemas de acesso aos recursos comuns, que precisam ser duplicados em sua
maioria. Mas em alguns casos isso é problemático, como por exemplo, a duplicação do barramento de acesso à memória.
No caso do banco de registradores, é comum haver várias portas de leitura e de escrita, para
permitir a leitura de vários operandos e a escrita de vários resultados a cada ciclo.
Um outro fator muito importante nas arquiteturas superescalares é o escalonamento das instruções que vão ser executadas. Devido aos problemas de dependências de dados e controle, algumas instruções não estão prontas para serem executadas. Esquemas mais simples de despacho,
simplesmente congelam o pipeline nesse caso. Esquemas mais sofisticados continuam a busca e
tentam executar as instruções fora-de-ordem, com mecanismos no ciclo de escrita que permitam a
retirada dessas instruções, e atualização do estado da máquina, na mesma ordem estabelecida
pelo programa objeto.
Exemplos de processadores com arquitetura superescalar são o Pentium IV da Intel, Athlon da
AMD e UltraSPARC da Sun.
Organização de Computadores
6.7.2.
Antônio Borges / Gabriel P. Silva
VLIW
VLIW é acrônimo para Very Long Instruction Word. São máquinas que exploram o paralelismo no
nível das instruções. Várias operações são executadas em paralelo em diferentes unidades funcionais, tais como em máquinas superescalares, a diferença está no controle do despacho e na
terminação das operações: nas máquinas superescalares: as dependências são resolvidas em
tempo de execução por um hardware dedicado, nas máquinas VLIW as dependências são resolvidas em tempo de compilação pelo compilador.
Em uma máquina VLIW, várias operações (instruções em uma máquina normal) são codificadas
em uma mesma instrução. A palavra de instrução é bastante longa, podendo conter várias operações (que operam sobre vários operandos) independentes. A posição de cada operação dentro da
palavra VLIW determina a unidade funcional que será usada. Deste modo, o hardware de despacho é simples.
O escalonamento das operações consiste em determinar as operações que serão executadas em
paralelo. Em uma máquina VLIW o compilador é responsável por esta tarefa. Operações que são
executadas em paralelo são atribuídas à mesma palavra de instrução. Dentro de um mesmo bloco
básico (seqüencial) estas instruções podem ser escalonadas com base no fluxo de dados. Já o
escalonamento que ultrapasse as fronteiras entre os blocos básicos exige técnicas mais elaboradas.
Exemplos de arquitetura do tipo VLIW são o Itanium da Intel e o Crusoe, da Transmeta.
Download