Arquitectura de Computadores
Notas de estudo
Alberto José Proença
1999/00
Os capítulos anteriores focaram a arquitectura dum computador sob a perspectiva duma instruction set architecture, e mais em particular dum determinado modelo de processador: do modelo que se encontra hoje em dia em qualquer sistema de computação, seja ele um sistema de informação electrónica ou apenas o posto de trabalho que se tem sobre a secretária (desktop computer).
Mais concretamente, os capítulos anteriores centraram a sua atenção na arquitectura do instruction set e respectiva concretização sob a forma dum processador de uso genérico (general purpose) e com uma organização do tipo RISC (Reduced Instruction Set Computer). Este capítulo pretende mostrar que existem outros modelos de organização - por ex., CISC (Complex Instruction Set Computer) - e de comercialização física de processadores - sob a forma de chips ou sob a forma de biblioteca de programas.
Um microprocessador não é mais do que a concretização física dum dado sistema digital - um processador de informação, ou simplesmente um processador - num único circuito integrado. Enquanto a tecnologia microelectrónica não permitia a construção de circuitos complexos fiáveis em áreas reduzidas, os primeiros circuitos integrados a beneficiar dos avanços desta área foram os microprocessadores e os circuitos de memória. Os primeiros microprocessadores não dispunham de capacidade de cálculo suficiente para serem verdadeiramente considerados de "processadores dum computador", nem possuíam um custo deveras atractivo para a sua utilização na electrónica de consumo. A situação sofreu contudo uma evolução bastante grande no fim da década de 70 e início da de 80.
No fim da década de 70 a I&D na área dos microprocessadores bifurcou-se: por um lado investiu na organização interna dos processadores com o objectivo de os dotar com instruction sets mais próximos das HLL's e poderem ser usados como processadores de computadores de uso genérico; por outro apostou na sua banalização como componente de electrónica, passando o microprocessador a incluir componentes de interface com o exterior, para além de alguma memória (e passando a designar-se por microcomputador ou por microcontrolador, ou ainda por embedded processor).
Este capítulo vai assim ser composto por 2 secções - uma dedicada a explorar cada uma dessas linhas e respectivas metodologias de programação - e por uma outra secção que analisa com algum detalhe um caso de estudo: a linha de processadores da Intel i86.
A bibliografia de base recomendada contém alguma informação sobre os tópicos abordados neste capítulo. São contudo recomendados os cap. 3.12 (sobre o PowerPC e o i80x86) e 3.15 (perspectiva histórica), bem como a informação adicional disponível na Internet relativa a essa mesma bibliografia (http://www.mkp.com/cod2e.htm), nomeadamente em "Web Extension I: Survey of RISC Architectures" (transcrito para o Anexo E das notas de estudo, e contendo uma secção em "Desktop RISC Architectures" e outra em "Embedded RISC Architectures") e em "Web Extension III: Another Approach to Instruction Set Architecture--VAX" (com uma metodologia equivalente à seguida nas aulas para a análise do i86).
O livro de Tanenbaum recomendado na bibliografia, organizado de acordo com os níveis virtuais presentes em qualquer arquitectura - nível do sistema digital, nível da microarquitectura, nível do instruction set architecture, nível do sistema operativo, nível do assembly, ... - vai acompanhando sempre ao longo destes capítulos com um exemplo significativo de cada um destes 3 tipos de processador: processador RISC de sistema de computação (SPARC V.9), processador CISC de sistema de computação (Pentium II), e processador embebido (PicoJava).
Para complementar a bibliografia referente aos processadores embebidos - nomeadamente as referências feitas nas aulas a alguns fabricantes e produtos - incluem-se neste capítulo apontadores a data sheets desses produtos, na secção 3. Arquitecturas Dedicadas.
A década de 80 ficou caracterizada entre os fabricantes de processadores como aquela em que a filosofia RISC - Reduced Instruction Set Computer - se impôs claramente sobre o modelo de arquitectura designado, como alternativa, de CISC - Complex Instruction Set Computer. O que distingue estes 2 modelos de arquitectura tem essencialmente a ver com os objectivos que orientaram ou motivaram o seu desenvolvimento.
As arquitecturas desenvolvidas durante a década de 60 possuíam conjuntos de instruções que tinham a grande preocupação de serem eficientes no código gerado, devido ao elevado custo da memória de acesso rápido, ou RAM; ao longo da década de 70 o desenvolvimento da microelectrónica permitiu a construção de processadores cada vez mais complexos, tendo levado os "arquitectos" de processadores a optarem por instruction sets cada vez mais complexos e mais próximos das instruções de programas HLL, numa tendência de se construir um processador cujo instruction set seria ... uma HLL.
Adicionalmente, a necessidade de se manter compatibilidade com gerações anteriores de processadores, a lenta evolução da ciência dos compiladores, e a elevada rapidez do funcionamento das memórias (face ao de um processador), manteve um modelo de programação, ao nível da linguagem máquina, assente numa utilização elevada da memória em detrimento do uso de registos (por exigirem compiladores mais complexos).
Por outro lado, a constatação nos finais da década de 70 de que uma grande parte do instruction set dos processadores não era usada pelos compiladores - e em particular as instruções mais complexas - pôs em causa a evolução dos processadores baseada simplesmente no aumento da complexidade dos instruction sets. Pior ainda, o verificar-se que um simples projecto académico de concepção e construção de um protótipo de um simples processador tinha produzido um modelo com desempenho próximo de sistemas comerciais de custo muitíssimo superior, obrigou a repensar todo o modelo básico de computação ao nível da linguagem máquina. Este projecto dum processador, que apostou na simplicidade do instruction set, passou a ser conhecido como o projecto dum Reduced Instruction Set Computer, i.e., duma arquitectura RISC.
Estes novos modelos - RISC - que estavam a ser propostos como alternativa aos modelos clássicos - que passaram a designar-se por CISC, Complex Instruction Set Computer, em oposição à outra designação - vieram também introduzir outras alterações que permitiram tirar ainda mais partido da simplicidade dos novos conjuntos de instruções. Incluem-se entre outras a possibilidade de partir a execução de cada instrução num conjunto de passos elementares e passíveis de execução em paralelo com desfasamento no tempo - em linha de montagem ou em pipeline - tendo como consequência o aumento da frequência do sinal de clock e conduzindo, no limite, à possibilidade de execução de uma instrução por ciclo máquina (impondo algumas restrições, como por exemplo, instruções de comprimento fixo, e não permitir operações com operandos em memória).
Este aumento na frequência do clock conduziu rapidamente a uma situação que penalizava acessos à memória, pelo que o aumento do n.º de registos no processador e uma maior complexidade e eficiência dos compiladores veio impor novos modelos de programação em linguagem máquina.
Objectivos genéricos dos modelos CISC e RISC
Resumindo a situação dos modelos CISC e RISC, e com base numa análise comparativa entre as figuras E.34 e E.1 (retiradas do Anexo E), poderemos dizer que:
IBM 360/370 | Intel 8086 | Motorola 68000 | DEC VAX | |
---|---|---|---|---|
Date announced | 1964/1970 | 1978 | 1980 | 1977 |
Instruction size(s) (bits) | 16,32,48 | 8,16,24,32,40,48 | 16,32,48,64,80 | 8,16,24,32,..., 432 |
Addressing (size, model) | 24 bits, flat/ 31 bits, flat |
4+16 bits, segmented |
24 bits, flat | 32 bits, flat |
Data aligned? | Yes 360/ No 370 | No | 16-bit aligned | No |
Data addressing modes | 2/3 | 5 | 9 | >= 14 |
Protection | Page | None | Optional | Page |
Page size | 2 KB & 4 KB | --- | 0.25 to 32 KB | 0.5 KB |
I/O | Opcode | Opcode | Memory mapped | Memory mapped |
Integer registers (size, model, number) |
16 GPR x 32 bits | 8 dedicated data x 16 bits |
8 data & 8 address x 32 bits |
15 GPR x 32 bits |
Separate floating-point registers | 4 x 64 bits | Optional: 8 x 80 bits |
Optional: 8 x 80 bits |
0 |
Floating-point format | IBM (floating hexadecimal) |
IEEE 754 single, double, extended |
IEEE 754 single, double, extended |
DEC |
Alpha | MIPS I | PA-RISC 1.1 | PowerPC | SPARC V8 | |
---|---|---|---|---|---|
Date announced | 1992 | 1986 | 1986 | 1993 | 1987 |
Instruction size (bits) | 32 | 32 | 32 | 32 | 32 |
Address space (size, model) | 64 bits, flat | 32 bits, flat | 48 bits, segmented | 32 bits, flat | 32 bits, flat |
Data alignment | Aligned | Aligned | Aligned | Unaligned | Aligned |
Data addressing modes | 1 | 1 | 5 | 4 | 2 |
Protection | Page | Page | Page | Page | Page |
Minimum page size | 8 KB | 4 KB | 4 KB | 4 KB | 8 KB |
I/O | Memory mapped | Memory mapped | Memory mapped | Memory mapped | Memory mapped |
Integer registers (number, model, size) | 31 GPR x 64 bits |
31 GPR x 32 bits |
31 GPR x 32 bits |
32 GPR x 32 bits |
31 GPR x 32 bits |
Separate floating-point registers | 31 x 32 or 31 x 64 bits |
16 x 32 or 16 x 64 bits |
56 x 32 or 28 x 64 bits |
32 x 32 or 32 x 64 bits |
32 x 32 or 32 x 64 bits |
Floating-point format | IEEE 754 single, double | IEEE 754 single, double | IEEE 754 single, double | IEEE 754 single, double | IEEE 754 single, double |
É interessante também analisar como os formatos de instruções variam tão pouco nestas 5 arquitetcuras RISC analisadas no Anexo E (a Fig. E.4 também é de lá retirada):
Vamos agora analisar algumas das diferenças básicas nos modelos de programação nestes 2 tipos de arquitectura:
Acesso a operandos em memória, em CISC e RISC
Uma das consequências do facto de as arquitecturas CISC disporem dum menor número de registos é a alocação das variáveis escalares, em regra, a posições de memória, enquanto que nas arquitecturas RISC a regra era a alocação a registos. Atendendo ao modelo de programação estruturada tão em voga nos anos 70, ao facto de a maioria das variáveis escalares serem locais a uma dado procedimento/função, e à necessidade de o modelo de programação ter de suportar o aninhamento e recursividade de procedimentos/funções, as arquitecturas CISC necessitavam de um leque rico de modos de endereçamento à memória, para reduzir o gap semântico entre uma HLL e a linguagem máquina.
Resume-se aqui as principais diferenças entre as arquitecturas CISC e RISC, nas facilidades de acesso a operandos que se encontram em memória:
Operações lógicas e aritméticas em CISC e RISC
Duas grandes diferenças se fazem notar entre estes 2 modelos: na localização dos operandos neste tipo de operações, e no n.º de operandos que é possível especificar em cada instrução. Resumindo o que foi visto anteriormente (complementado com exemplos na aula):
Modelo de programação de procedimentos/funções
Tal como referido anteriormente, a grande diferença entre estes 2 modelos está patente na estrutura de gestão das variáveis dum programa, em especial em programação estruturada com uso de procedimentos e funções.
Associado a cada procedimento/função existe sempre um conjunto de conceitos a reter e pertinentes na compilação para linguagem máquina:
Este assunto foi sendo analisado em capítulos anteriores. Resumindo o que foi visto anteriormente:
Análise comparativa do exemplo bubble sort
Para uma melhor compreensão de todas estas questões a análise comparativa do exemplo de buble sort é um excelente auxiliar. A sua apresentação detalhada e respectiva programação em linguagem máquina foi já usada anteriormente como forma de introduzir a programação de procedimentos/funções no modelo RISC (MIPS). Este exemplo aparecia de novo no apêndice E da primeira edição do livro recomendado - fig E.7 e E.8 - e disponível presentemente apenas na "Web Extension III: Another Approach to Instruction Set Architecture--VAX" conforme referido no início do capítulo. Contudo, o modelo de arquitectura CISC aí referido não é o do i86, motivo porque se repete aqui o exercício apresentado na aula.
A ênfase na análise deste exemplo foi colocada a 2 níveis:
A estrutura do activation record - apenas necessária numa arquitectura RISC quando o nº de registos não é suficiente para todas as variáveis locais e/ou parâmetros do procedimento/função - é constituída pelos seguintes campos no caso do i86 (análise apresentada na ordem de preenchimento da stack):
int v [10000] ;
sort ( int v [ ], int n ) bubble sort
{
int i , j ;
for ( i = 0 ; i < n ; i = i + 1 )
for ( j = i ; j >= 0 && v [ j ] > v [ j + 1 ] ; j =
j - 1 ) {
swap ( v , j ) ;
}
}
MIPS versus i86
Salvaguarda de registos |
||
sort: addi $sp, $sp, -20 sw $s0, 0($sp) sw $s1, 4($sp) sw $s2, 8($sp) sw $s3, 12($sp) sw $ra, 16($sp) |
sort: push BP mov BP, SP push AX push BX push SI |
|
Corpo do procedimento |
||
Parâmetr (MIPS) Var locais (i86) |
move $s2, $a0 move $s3, $a1 |
sub SP, 4 |
Loop externo | add $s0, $0, $0 for1tst: slt $t0, $s0, $s3 beq $t0, $0, exit1 |
mov word ptr [BP-8], 0 for1tst: mov AX, [BP-8] cmp AX, [BP+4] jge exit1 |
Loop interno | addi $s1, $s0, -1 for2tst: slti $t0, $s1, 0 bne $t0, $0, exit2 muli $t1, $s1, 4 add $t2, $s2, $t1 lw $t3, 0($t1) lw $t4, 4($t1) slt $t0, $t4, $t3 beq $t0, $0, exit2 |
dec AX mov [BP-10], AX for2tst: cmp word ptr [BP-10], 0 jl exit2 mov BX, [BP+6] mov SI, [BP-10] shl SI, 1 mov AX, [BX+SI] cmp AX, [BX+SI+2] jle exit2 |
Acesso a subrotina | move $a0, $s2 move $a1, $s1 jal swap |
push BX mov AX, [BP-10] push AX call swap add SP, 4 |
Loop interno (cont) | addi $s1, $s1, -1 b for2tst |
dec word ptr [BP-10] jmp for2tst |
Loop externo (cont) | exit2: addi $s0, $s0, 1 b for1tst |
exit2: inc word ptr [BP-8] jmp for1tst |
Recuperação de registos |
||
exit1: lw $s0, 0($sp) lw $s1, 4($sp) lw $s2, 8($sp) lw $s3, 12($sp) lw $ra, 16($sp) addi $sp, $sp, +20 |
exit1: add SP, 4 pop SI pop BX pop AX pop BP |
|
Retorno do procedimento |
||
jr $ra | ret |
As secções anteriores analisaram modelos alternativos de arquitecturas de processadores, que tinham como principal objectivo melhorar o desempenho de execução de instruções - performance - pois a sua principal utilização era em sistemas de computação.
Os processadores usados em sistemas de computação possuem as seguintes caracterísiticas:
As arquitecturas dedicadas de processadores têm como principal objectivo a resolução de problemas específicos de processamento de informação ao mais baixo custo e com um desempenho aceitável. São normalmente parte da electrónica associada a um equipamento - sendo por isso também conhecidos como processadores embebidos - e na maioria dos casos deempenham tarefas de controlo - sendo por esse facto e aliado à sua integração num único chip, também designados por microcontroladores.
Os microcontroladores possuem as seguintes caracterísiticas:
Alguns destes microcontroladores tem uma área aplicacional com exigências computacionais bem específicas, nomeadamente no domínio do processamento de sinais digitais, sendo por isso também conhecidos como DSP's (Digital Signal Processors); a sua característica mais importante e que os distingue de outros processadores é o suporte a operações MACs (multiplier-accumulators).
Vamos analisar alguns exemplos de microcontroladores e DSP's, com figuras retiradas de data sheets dos seguintes produtos:
Análise do instruction set dum microcontrolador: Microchip PIC17C75x
Estrutura de um microcontrolador: Microchip PIC17C75x
Registos de um microcontrolador: Microchip PIC17C75x
Estrutura de um DSP disponibilizado como uma megafunção na construção de um ASIC: SGS-Thomson D950
Estrutura de um DSP (core): SGS-Thomson D950
Registos de um DSP (core): SGS-Thomson D950
Operações de MAC num DSP especial: Image and Signal Processor SGS-Thomson IMSA110