Processadores RISC

  1. Conceitos básicos
  2. RISC
  3. Pipeline
  4. Restrições
  5. Problemas de processamento em pipeline
  6. SPARC - Scalable Processor ARChitecture
  7. Alpha
  8. Terminologia

Conceitos básicos

Conceitos diferentes:

Pipeline é uma forma de implementação de microprocessadores, pelo que pode ser usado para implementar microprocessadores que não se caracterizem como RISC.

No entanto, um dos elementos mais habitualmente usados para identificar um processador RISC é a existência de pelo menos um pipeline. Contudo existem processadores RISC que não têm pipeline (PTSC Ignite) e outros que não são RISC e que têm pipeline (Intel Pentium, é um processador CISC no que respeita ao seu conjunto de instruções, mas traduz essas instruções para um conjunto de instruções outras RISC, que são usadas internamente pelo pipeline.) .

RISC

O conceito de processador RISC baseia-se na premissa de que será menos eficiente executar uma instrução complexa do que executar o conjunto de instruções simples equivalente.

Assim, os processadores RISC têm por objectivo simplificar o conjunto de instruções em diversas dimensões por forma a maximizar esta premissa.

Para isso, um processador RISC caracteriza-se por:

Pipeline

O processamento de uma instrução é composto pelo menos por cinco fases:

O resultado é um pipeline de cinco estágios:

Como o estágio de instruction decode (descodificação) não necessita de aceder à memória (recurso partilhado), pode ser realizado em simultâneo com a fase de operand fetch (que usa a memória). O resultado é um pipeline com 4 estágios.

Este corresponde a uma abordagem minimalista e original, mas hoje em dia os pipeline não se limitam a 4 ou cinco estágios, mas podem chegar a 20 ou 30 estágios (Intel Pentium 4).

O princípio operacional dum pipeline é que podem estar em processamento várias instruções em simultâneo, pois cada um dos estágios é logicamente independente dos outros.

 

O resultado é que em execução óptima, o processador executa até uma instrução por ciclo de relógio, mesmo que cada instrução demore mais do que um ciclo de relógio a ser processada.

Portanto, teoricamente e na melhor das hipóteses, é possível executar uma instrução por cada ciclo de relógio, menos os ciclos iniciais em que os estágios não são completamente utilizados em processamento.

Ou seja:

c = i + e - 1

Restrições

No entanto, para que todo o conceito/processo funcione é necessário que determinadas restrições se verifiquem. Nomeadamente, é prioritário que todas as instruções permaneçam em cada estágio o mesmo tempo, para que:

Porque o processamento é diferente de estágio para estágio, para que o processo ocorra num único ciclo de relógio é necessário analisar o problema a resolver e encontrar soluções convenientes.

Instruction fetch

Problema:

Solução:

Instruction decode

Problema:

Solução:

Operand fetch

Problema:

Solução:

Execution

Problema:

Solução:

(Memory)

Problema:
Solução:

Write-back

Problema:

Solução:

Portanto, é fundamental que sejam observadas as seguintes restrições:

Problemas de processamento em pipeline

No entanto, este conceito de processamento tem alguns problemas, motivados pelo facto de estarem em processamento várias instruções em simultâneo.

São identificados dois tipos de problemas:

Falta de operandos (Data hazards)

A falta de operandos ocorre quando o resultado de uma instrução é usado na instrução da seguinte. Como o resultado da primeira instrução só se torna efectivo (write back) quando a seguinte já está a executar (execution), então os valores dos operandos da segunda instrução não estão correctos.

Considere-se o código seguinte:

	mov ax, var1
mov bx, var2
add ax, bx
instr4

que corresponde à seguinte representação de execução:

No estágio de execução da instrução add ax, bx, o valor de bx não é o correcto, pois a instrução anterior (mov bx, var2) ainda não escreveu o valor no registo bx.

Existem duas soluções possíveis:

A solução de “forwarding” corresponde a fazer o valor passar directamente para o andar de execução (ou outro) sem passar pelos registos.

A solução de “interlocking” corresponde a fazer parar a instrução seguinte até que o valor correcto dos operandos esteja disponível. Assim, o exemplo anterior teria a seguinte execução:

A solução por software implica um de dois estratagemas:

Fluxo de execução (Control hazards)

Quando uma instrução de salto (branch) está a ser executada, já a seguinte também está a ser executada. Mas a instrução a executar a seguir é dependente do resultado da instrução de branch, pelo que não é possível antes disso determinar qual a instrução seguinte.

Considere o exemplo seguinte:

	inicio:
mov cx, var1
mov dx, var2
mov ax, var3
mov bx, var4

% calcula o menor de dois valores e coloca em ax
cmp ax, bx
jle fimteste
bxmenor:
mov ax, bx
fimteste:
add cx, ax
sub dx, ax

A execução corresponde ao modelo seguinte, considerando que o processador tem e aplica o mecanismo de “forwarding”:

Algumas instruções irão portanto ser processadas sem que haja garantias de que devam ser executadas. No caso de não deverem ocorre uma “bubble”. É o caso das instruções mov ax, bx (corresponde a colocar em ax o menor valor entre ax e bx) e add cx, ax (corresponde ao processo a seguir ao cálculo do menor valor). Ambas irão ser iniciadas independentemente do resultado da instrução “jle fimteste”.

Em função do resultado da instrução jle fimteste, duas hipóteses existem:

Os efeitos do processamento errado duma bubble têm de ser desfeitos (penalty), o que causa complicações à gestão do pipeline. Esta não é normalmente uma solução interessante ou fácil de implementar, pelo que é evitada.

O ponto de partida da solução é o denominado “branch delay slot”, a tal "bubble", que pode ter comprimento de 1 ou mais ciclos. Um branch delay slot corresponde a um ciclo de relógio (slot) em que não é iniciada uma nova instrução por causa dum branch condicional. O comprimento do branch delay slot varia de processador para processador, e quanto mais cedo a decisão de salto for tomada, menor será o seu comprimentos e portanto menor será a penalização. No caso anterior o comprimento da bubble é 2 (decisão sbore o branch é tomada no terceiro estágio do pipeline), enquanto no DLX é de 1(decisão tomada no segundo branch). Há processadores cujo comprimento do delay slot é de 5-10 ou mesmo mais slots, mas como a frequência de relógio é muito elevada (muitos estágios, frequência elevada), as penalizações acabam por não ser maiores que nalguns processadores em que o branch delay slot tem comprimento menor mas cujo ciclo é maior que nos outros.

Existem várias potenciais soluções:

No caso do código anterior, seria possível definir uma instrução de “branch and execute” que executasse as instruções mov cx, var1 e mov dx, var2 nos 2 branch delays slots considerados anteriormente.

com branch condicional com branch e execution
inicio:
mov cx, var1
mov dx, var2
mov ax, var3
mov bx, var4

% calcula o menor de dois valores e coloca em ax
cmp ax, bx
jle fimteste
bxmenor:
mov ax, bx
fimteste:
add cx, ax
sub dx, ax
inicio:
mov ax, var3
mov bx, var4

% calcula o menor de dois valores e coloca em ax
cmp ax, bx
jle fimteste
mov cx, var1
mov dx, var2
bxmenor:
mov ax, bx
fimteste:
add cx, ax
sub dx, ax

Estas instruções podem ser usadas pois não provocam dependências nas seguintes (mov ax, var3 e mov bx, var4) pois os seus resultados só vão ser usados em add cx, ax.

Portanto, o “branch and execute” corresponde em muitas situações a uma reordenação de instruções sem a necessidade de termos dois saltos.

SPARC - Scalable Processor ARChitecture

Arquitectura

Register Window

 
 

Alpha

Originalmente a arquitectura Alpha é caracterizada por:

Outras características tão ou mais importantes:

Terminologia

Pipeline

Super Pipeline

Pipeline com muitos estágios.

Processador super-escalar

Quando existe mais do que uma unidade de execução no processador.

Normalmente a existência de mais do que uma unidade de execução está associada a processadores RISC (com pipeline), mas o número de unidades de execução é independente do número de pipelines.

Branch prediction

Determina qual o caminho mais provável que o teste+salto irá tomar. Há várias formas de "branch prediction", nomeadamente:

Execução expeculativa

Ordenar/Executar as instruções em função do resultado do branch prediction.

Execução fora de ordem (out-of-order execution)

	mov ax,var1
mov bx,var2
add ax,bx
; as instruções seguintes não dependem das anteriores
; portanto podem ser executadas fora da ordem
mov cx,var4
mov dx,var5
add cx,dx
mov var6,cx

Renomeação de registos

	mov ax,var1
mov bx,var2
add ax,bx
mov var3,ax
; as instruções seguintes não dependem das anteriores
; mas estão a usar os mesmos registos
se usarmos um mecanismo de “register renaming” então as
; instruções usarão outros registos e já serão executadas “fora da ordem”
mov ax,var4
mov bx,var5
add ax,bx
mov var6,ax

Buffer de reordenação

Local de reserva dos resultados das instruções, antes de serem colocados ordenadamente segundo o programa original nas suas localizações definitivas.

Reservation stations

Também denominadas filas de espera de instruções.

Última actualização: 2006-10-06