Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Trabalho de Microprogramação
1. Conceitos de Microprogramação
Em vista desse problema, surgiu a necessidade de uma arquitetura com uma unidade de
controle (UC) maleável. Esta unidade, que manipula o estado do processador através de sinais de
controle, poderia ser implementada de maneira a facilitar o trabalho dos projetistas e a evolução da
arquitetura do processador.
Outra coisa a se notar é que o apontador de microinstruções pode sofrer desvios, assim como
o PC num código assembly. Os desvios podem inclusive ser condicionais, levando em conta o valor
atual de registradores da máquina comparados entre si, comparados com imediatos passados no
código assembly (e obtidos através do registrador de instrução) ou comparados com constantes
embutidas nas próprias palavras de microinstrução (uma outra utilidade dos bits, como foi
adiantado no parágrafo acima).
2. Introdução ao Problema
Para demonstrar o uso de uma memória microprogramada da forma como foi enunciada na
seção 1, este trabalho consiste em utilizar o Escape DLX (ver seção 3) para programar e avaliar dois
programas distintos que implementam um algoritmo de geração de números pseudo-aleatórios.
3. Simulador
Neste trabalho, foi utilizado o Escape DLX [3], um simulador baseado na arquitetura RISC
microprogramada proposta por by John L. Hennessy and David A. Patterson. Este simulador é
altamente customizável, sendo possível alterar diversos aspectos de sua arquitetura. Dentre eles,
estão o tamanho da memória, formato do código da instrução, tamanho do microcódigo e etc.
Além disso, o simulador ainda conta com uma arquitetura de pipeline (que não será abordada aqui).
O propósito deste trabalho é implementar uma nova instrução neste simulador. Para isto,
utilizamos o projeto default do simulador como base.
Depois disso, alteramos a jump table. Isto foi necessário para que, quando a UC decodificar
a instrução RND, saiba para qual endereço do microcódigo deve desviar. Por isso, inserimos o
opcode RND e o rótulo RND (que recebeu o mesmo nome por questões de legibilidade) na Jump
Table 1.
4. Apresentação do algoritmo
Como já foi dito anteriormente, o método do gerador congruente linear [2] é o que usaremos
na implementação deste trabalho.
Onde:
m = 2^32
a = 1664525
c = 1013904223
int n = 100
long r[] = new long[n+1];
r[0] = 0x5EED;
long m = 4294967296L;
long a = 1664525;
long c = 1013904223;
Observe que não é necessaria a operação de Mod m enunciada na fórmula, visto que m=2^32
e a palavra de dados do Escape DLX é de 32 bits; consequentemente, a máquina truncará os bits
excedentes e preservará os 32 bits menos significativos.
Segue abaixo a codificação do programa 2, que utiliza a nova instrução RND e gera 100
números a partir da posição de memória 0x20. O seed utilizado tem o valor 0x5EED.
A figura 3 (esquerda) é o dump da memória após a execução do código acima. Ele pode ser
comparado com a saída do mesmo algoritmo programado em alto nível (mesma figura, direita) pelo
código em Java da Listagem 1.
Continuando, o valor de seed é movido para o registrador AT para ser multiplicado por a e
somado a c. O registrador CO é utilizado como contador do loop (recebe N passado como
parâmetro da instrução) e P (ponteiro) auxilia no cálculo do endereço de memória onde será
armazenado o número gerado.
0036 S2S1 T CA CA
003A S1 A AT
003C S1 A CO
003E MUL CA AT AT
Para executar os testes, optamos por calcular analiticamente o tempo de execução dos
programas para poder utilizar a opção de execução de múltiplos ciclos do simulador. Para isso,
tivemos que contar o tempo de execução de cada instrução e a partir disto calcular o valor de
execução total do programa.
= 4 Tm + 20 + (Tm + 7) * N
= 12 Tm + 32 + (10 Tm + 27) * N
Com isso, pudemos considerar 2 cenários para o tempo de acesso à memória: 9 ciclos
(testado no simulador) e 200 ciclos (hipotético).
Tm = 9 ciclos Tm = 200 ciclos
140000 2500000
Tempo de Execução (Ciclos)
0 0
0 500 1000 1500 0 500 1000 1500
Números Gerados Números Gerados
Como podemos observar, o uso da instrução RND implementada em microcódigo fez com
que o tempo de execução diminuísse consideravelmente. Isso se deveu principalmente à economia
com o tempo de fetch de cada instrução (pois a instrução RND faz o papel de diversas instruções no
programa de código em assembly, reduzindo consideravelmente o número de instruções a serem
buscadas na memória), como também ao fato de as constantes utilizadas pelo algoritmo não
gerarem fetchs adicionais, por já estarem embutidas na memória da UC.
6. Referências