Académique Documents
Professionnel Documents
Culture Documents
Centro de Tecnologia
Departamento de Informática
1.1. Histórico
1.2. Regras
Sacrifique tudo para reduzir o tempo de ciclo da via de dados.
Microcódigo não é mágico.
Operando1
Resultado
Operando2
3. Projetar as instruções que executem as operações chaves, estas devem utilizar de
forma ótima as vias de dados, ou seja, cada instrução deve utilizar um único ciclo da
via de dados.
4. Adicionar novas instruções somente se elas não diminuírem a velocidades da
máquina
5. Repetir este processo para outros recursos
1.5. Registradores
Os compiladores escritos para máquinas RISC fazem uso intenso de registradores, com
intenção de reduzir o tráfego na via de dados em comunicação com a memória.
Um processador RISC não tendo microcódigo, não ocupa área de memória para tal tipo de
operação, portanto, pode construir um grande número de registradores utilizando esse
espaço.
1.7. Pipelining
Pensemos no seguinte exemplo: um homem sozinho assenta os azulejos de uma cozinha.
Ele precisa buscar cada peça na pilha, acomodar a massa, colocar o ladrilho. Se ele utilizar
os serviços de um ajudante, pode eliminar a tarefa de buscar os azulejos e se concentrar no
assentamento. Simples, duas pessoas trabalhando termina o serviço mais rápido.
A técnica do pipelining é muito semelhante ao exemplo acima e também à uma linha de
montagem de carros. Cada funcionário faz sua tarefa e no final o carro está pronto mais
rápido que se cada pessoa montasse um deles.
Uma CPU pipelined deve permitir a execução total da instrução por estágios, por exemplo,
busca da instrução na memória; execução da instrução e referências memória (quando
houver). Se utilizando esta técnica uma instrução for iniciada a cada ciclo, mesmo que ela
demore mais de uma para ser finalizada, em média a regra estaria cumprida. Em cinco
ciclos, cinco instruções foram iniciadas.
1 2 3 4 5
Busca da instrução A B C D E
Execução da instrução A B C D
Referência a memória B
Para amenizar este tipo de problema, e muitas vezes realmente solucioná-lo, o compilador
deve ser bom o suficiente para garantir que a próxima instrução, não vai utilizar o dado que
está sendo trazido da memória. Isto pode ser feito com uma instrução que não seja a que
esteja na seqüência escrita pelo programador. O compilador deve organizar a execução das
instruções visando o resultado final, tapando os "buracos" que surgirem por execução de
instruções de mais de um ciclo, com "coisas úteis" ao ínves de NOPS's.
Outras instruções além da que acessam a memória podem atrapalhar o processamento. Um
JUMP condicional, onde o compilador não pode prever o resultado, obriga algumas vezes o
esvaziamento do pipeline para executar o desvio.
Nestes casos as técnicas utilizadas se chamam, repectivamente, carga atrasada e desvio
atrasado, ambas resolvidas pelo compilador.
1.10.6. Conclusão
O crescimento do número de modos de endereçamento em uma máquina, implica na perda
de velocidade e também no aumento da complexidade. Porém, apesar do nome, uma
máquina RISC poderia ter muitas instruções, contanto que elas executassem em um único
ciclo de via de dados e tivessem o formato fixo. O comprometimento nesse caso, seria o de
construir uma unidade de decodificação bastante complexa, já que ele cresceria
exponencialmente com o número de instruções.
2. Compiladores
compilador
Instrução em alto nível Código de máquina
Quando chega-se justamente ao ponto mais controverso no debate entre CISC x RISC, o
desenho do compilador.
Os defensores do CISC alegam que a distância semântica conduz a ineficiência de
execução, programas excessivamente grandes e compiladores complexos e argumentam
que a disponibilidade de instruções de alto nível e a habilidade de especificar múltiplos
operandos baseados na memória, simplifica o desenho do compilador. Naturalmente, isto
leva diretamente para um conjunto de instruções grande, dezenas de modos de
endereçamento e muitas declarações da linguagem de alto nível implementadas em
firmware.
Surgem divergências entre as estruturas estudadas e as implementadas, como exemplo
pode-se citar a instrução LOOP utilizada já no PC-xt para controle de laço de repetição.
Esta instrução repete um bloco de instruções por um número fixo de vezes como o "para-
faça", mas faz isto, pelo menos uma vez como o "repita-até".
mov cx, 32 ;estabelece o critério de parada
Aqui: ....
....
loop aqui ;decrementa cx, e desvia para aqui se cx > 0
Este bloco poderia facilmente ser traduzido com a utilização de decrementos, comparação e
desvio condicional, porém, nota-se aqui que a arquitetura CISC não economiza instruções.
Fica então a pergunta: qual é a arquitetura que melhora o desenho do compilador? Sabendo-
se que este compilador deve ser um compilador otimizador, irá produzir códigos de
execução mais rápidos. Uma vez que as instruções devem ocupar um ciclo em média, o
compilador deve reorganizar a seqüência das instruções, de forma a tapar os "buracos"
gerados pelas de maior tempo.
3.1. Histórico
A tecnologia RISC foi desenvolvida pela IBM nos anos 70 e o primeiro chip surgiu em
1980. Sua proposta baseou-se em um conjunto reduzido de instruções, sendo definidas
apenas as mais freqüentemente utilizadas e se evitando o uso de microcódigos. As
instruções também seriam simplificadas, trabalhando com apenas um operando.
As operações enfatizavam o uso de registradores, sendo o acesso à memória limitado a
instruções tipo leitura e escrita na memória (load/store). Assim, o processador gastaria
apenas um ciclo por instrução. Porém, o que sucedeu não foi tão simples assim, pois havia
muita dificuldade em se escrever programas complexos utilizando um conjunto muito
reduzido de instruções. Então este conjunto foi incrementado com novas instruções, como
as necessárias para trabalhar com memória virtual, multiprocessamento e assim por diante.
A tecnologia RISC começou a ser promovida no mercado com o surgimento das estações
de trabalho científicas, pois sua atividade básica é "CPU bound". Os chips CISC (Complex
Instrution Set Computing) de aplicação mais geral - típicas de ambientes comerciais - não
ofereciam a velocidade necessária aos trabalhos com extensas manipulação de números e
visualização gráfica. Em ambiente comercial, por seu lado, é necessário considerar todo o
conjunto que compõe o sistema, como CPU, memória, velocidade de discos, sistema
operacional e software de aplicação.
Uma comparação levando em conta apenas o processador e sua técnica, não é correta.
Muitos dos fatores que aumentam a velocidade de um processador RISC, não são inerentes
a esta tecnologia (como uso de cache, pipeline de instruções e grande número de
registradores na CPU), sendo que estes recursos estão disponíveis a qualquer projeto de
computador, sendo usados também em máquinas CISC.
A análise dos processadores do mercado mostra que nos aspectos de mips ou operações
aritméticas com números inteiros (SPEC Integer), o desempenho dos chips RISC e CISC
são similares; em ponto flutuante (SPEC Floating Point) os RISC tendem a apresentar
resultados melhores, embora o Pentium lhes seja equivalente.
4. Exercícios Resolvidos
ii. Qual o número máximo de instruções que um processador deve ter para ser
considerado RISC?
No princípio, a base da arquitetura RISC pretendia que esta possibilitasse instruções
simples e que fossem as mais freqüentemente utilizadas, construindo um conjunto
otimizado de instruções. Um aspecto importante era permitir a otimização da
implementação de pipeline nesta arquitetura, não o número de instruções que ela
disponibilizaria. Algumas operações exigem a implementação de operações que não podem
ser feitas em um único ciclo, exigindo que a arquitetura RISC tivesse ao menos algumas
instruções mais complexas, como por exemplo para lidar com gerenciamento de memória
virtual, multiprocessamento, etc. A partir daí, várias máquinas lançadas no mercado vêm
apresentando número variável de instruções, o que deu margem a várias informações
desencontradas sobre o que vem a ser uma máquina RISC e uma máquina CISC. Por
motivo de marketing muitas máquinas com características de funcionamento de arquiteturas
CISC são denominadas RISC pelo simples fato de apresentarem menos de 100 instruções.
O máximo que se pode conseguir, é basear este número em máquinas conhecidas: a
Motorola 88000 apresenta 51 instruções, já a MIPS R4000 possui 94 instruções. Apesar de
ter sido cogitado no principio a criação de uma máquina com uma única instrução
[FALTOU REFERÊNCIA], parece que seguimos o caminho contrário, e as máquinas RISC
aumentam seu número de instruções a cada versão.
Segundo um popular jornal de computação [FALTOU REFERÊNCIA], processadores com
menos que 100 instruções são considerados RISC. Porém não existe nenhuma restrição
formal quanto ao número máximo de instruções de um processador RISC, desde que cada
instrução seja executada em um ciclo da via de dados. O único problema real é que a
complexidade do bloco decodificador, OP, cresce exponencialmente com o número de
instruções e assim consome proporcionalmente crescentes áreas da pastilha.
iii. Discorra sobre papel do compilador para um RISC (pode usar comparações
como o CISC)
FILOSOFIA DO PROJETO RISC: Deixar tanto trabalho quanto for possível a cargo do
compilador.
De certa forma, o trabalho para se alcançar os objetivos dos projetistas ao criar arquitetura
RISC, simplificar o conjunto de instruções e otimizar o funcionamento do processador,
recaiu sobre o compilador. Pelo fato de não mais se utilizar microcódigo para fazer a
interpretação da linguagem de máquina o trabalho do compilador se tornou um pouco mais
complicado. Agora, além de gerar microcódigo para programas de usuários, ele deve
administrar toda a seqüência de pipeline do programa, e garantir seu funcionamento
otimizado, de forma a não permitir ciclos vazios, além de possibilitar que operações com
dados da memória possam ser feitas em média em um ciclo de via de dados. Logo, a tarefa
executada pelo microcódigo da arquitetura CISC passa a ser do compilador.
A tecnologia do compilador é um fator crítico do projeto RISC. Compiladores otimizados
devem transportar toda a complexidade do hardware para a fase de compilação.
Para manter a simplicidade do hardware, o compilador é projetado para lidar com
características intrincadas da arquitetura RISC, como cargas, armazenamento e desvios
atrasados, que aumentam consideravelmente a complexidade do compilador.
O compilador deve fazer uso intensivo de registradores para reduzir o tráfego de memória,
para evitar instruções que demoram mais do que um ciclo da via de dados para serem
completados. Consequentemente, é essencial que o compilador RISC seja capaz de otimizar
da melhor maneira possível o uso de registradores, levando em consideração que as
instruções comuns não podem utilizar operandos de memória. Para viabilizar esta
otimização são utilizados algoritmos de alocação de registradores sofisticados. Apesar
destes algoritmos melhorarem o código colocando mais variáveis em um número limitado
de registradores, eles também aumentam a complexidade do compilador.
Além disso, o compilador RISC deve, sempre, buscar produzir um código correto e
eficiente, tentando contornar os problemas acarretados pelos saltos atrasados, por exemplo.
A partir destes fatos, constata-se que a arquitetura RISC também possui alguns problemas,
assim como a arquitetura CISC, guardadas as devidas proporções.
iv. Descreva a passagem de parâmetros entre procedimentos em uma máquina:
a)CISC
A maioria dos procedimentos recebem parâmetros fornecidos pelo procedimento que
chama. Nas máquinas CISC, estes parâmetros são empilhados um de cada vez, pelo
processo que chama, no início da execução da instrução CALL. O procedimento chamado,
busca na pilha os parâmetros esperados. Este processo se baseia 100% na comunicação com
a memória.
b)RISC
O objetivo de toda máquina RISC é executar uma instrução por ciclo, em média. Uma vez
que LOAD e STORE requerem, normalmente, dois ciclos, quanto menos instruções deste
tipo forem utilizados, maior será a “eficiência” da máquina.
Grande parte do tráfego de memória total está relacionada a chamadas de procedimentos.
Parâmetros têm que ser passados, registradores têm que ser salvos, e o endereço de retorno
tem que ser empilhado na chamada e desempilhado no retorno. Todas estas ações geram
alto tráfego de memória.
Uma forma de eliminar parte deste tráfego é utilizar um método chamado janelas
sobrepostas de registradores, adotado por algumas máquinas RISC. Quando janelas
sobrepostas são utilizadas, a CPU contém um grande número de registradores, mas em cada
momento somente um subconjunto deles, 32 registradores de 32 bits, é visível para um
programa. Este conjunto é dividido em quatro grupos distintos com 8 registradores cada.
• O primeiro grupo (R0 a R7) guarda variáveis globais e ponteiros; esses são utilizados
por todos os procedimentos ao longo do programa, sendo da responsabilidade decidir o
que colocar em cada registrador.
• O segundo grupo, R8 a R15, guarda os parâmetros de entrada; evita o uso de pilha, que
é utilizada somente se o número de parâmetros exceder 8, neste caso, o último
registrador contém o endereço da pilha onde se encontra o restante dos parâmetros. Não
colocar os parâmetros na pilha elimina STORE’s quando eles são passados e elimina
LOAD’s quando eles são acessados pelo procedimento chamado.
• O terceiro grupo , R16 a R23, estão disponíveis para as variáveis locais, o excedente
também vai para a pilha.
• O quarto grupo de registradores, R24 a R31, é utilizado para passar os parâmetros para
os procedimentos chamados, sendo a pilha utilizada somente na falta de registradores
para os parâmetros.
Uma máquina RISC pode ter cache. Isto dependerá da aplicação para o qual a máquina é
projetada. A cache oferece muitas características que podem ser benéficas para um projeto
RISC, entre elas, a possibilidade de armazenamento de trechos de código, que é impossível
para os registradores. Além disso, os “on-chip caches”, que quando cronometrados se
apresentam tão rápidos quanto o processador.
Conclui-se que a decisão correta, quanto a implementação ou não da memória cache, deve
ser baseada numa ponderação sobre todas características debatidas no item anterior.
a)
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 0 0 0 1 1 1 0 0 1 0 1 0 1 0 1 1 1 1 0 0 0 0 0 1 1 1 1 0 1
rd op rs1 sisconst1a
Verificando o primeiro campo da instrução (da esquerda para direita), poderia-se dizer que
se trata de uma instrução para load ou store. Sendo o bit 13 igual a 1, sabemos que se trata
de uma instrução de store, entretanto, como o campo op (bits 19 a 24) armazena uma
seqüência de valores que não pertence a tabela de códigos de operação de load e store, é
descartada esta possibilidade. O valor do primeiro campo também poderia indicar que a
instrução seja uma instrução geral das máquinas SPARC, porém, o campo dos bits 19 a 24
também não fazem parte da tabela de instruções, podemos concluir que se trata de uma
instrução inválida.
b)
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1 0 1 0 1 1 1 1 0 1 0 1 0 1 1 1 0
Os dois primeiros bits da instrução com valores 0 e 1 indicam uma instrução call. Não
existem demais exigências para comprovação da instrução, os demais bits (0 a 29) formam
o endereço de desvio e, desta forma, estão disponíveis para o contador do programa.
c)
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1
Devido aos valores da seqüência de bits 22 a 24 não corresponderem a nenhum valor da
tabela de instruções de desvio condicional ou instruções sethi, descartou-se a possibilidade
de serem este tipo de instrução e, considerando a seqüência dos bits do campo op (22 a 24)
concluiu-se que se trata de uma instrução não implementada com código de campo
correspondente a instruções ilegais.
d)
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0 1 0
A instrução acima corresponde a instrução de subtração, caracterizado pelo valor 10 dos
primeiros campos e pela seqüência de bits do campo op (22 a 24) que correspondem a
instrução subcc. O campo rd (25 a 29) corresponde ao campo de registrador de destino, no
caso o %R19, o campo rs corresponde ao registrador origem (14 a 18), um segundo
operando origem pode ser um registrador (0 a 4) ou um valor constante (0 a 12). Na
instrução acima, trata-se de um valor constante no campo siconst (1FOA h).
e)
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 1 1 0 1 0 0 1 1 0 1 0 1 0
Esta é outra instrução call, foi analisada da mesma forma que a instrução da letra b.
a) if (delta > 0)
z=0;
else
y=0;
.text
start: set delta, %r1
ld [%r1], %r2 ! delta é armazenado em %r2
set z, %r1
ld [%r1], %r3 ! z é armazenado em %r3
set y, %r1
ld[%r1], %r4 ! y é armazenado em %r4
b) conta=0;
while (conta <0){
y=conta;
conta++;
}
.text
start: set conta, %r0
ld [%r1], %r4 ! conta é armazenada em %r4
set y, %r0
ld [%r1], %r2 ! y é armazenado e %r2
5. Bibliografia
TANENBAUM, A., Organização e Arquitetura de computadores, Prentice Hall do Brasil,
1990
STALLINGS, W., Computer Organization and Architeture, Prentice Hall, 1996
5.1. Internet
http://minerva.ufpel.tche.br/~machado/risccisc/pagina.html
http://www.din.uem.br/sica/apostilas
http://www.sunworld.com/sunworldonline/swol-09-1999/swol-09-insidesolaris.html