Buscar

Aula09 ArqComp ADS 2014 1

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 30 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 30 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 30 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Arquitetura de Computadores (ARQI1) 
ADS171 
Aula 09: 
 
 Execução de código 
 Conceito 
 
 
Os processadores trabalham apenas com informações digitais – 0s e 1s – formando um 
conjunto de bits (byte, word, doubleword, quadword). Um processador contém um 
repertório – conjunto ou set – de instruções, as quais são compreendidas pelo 
processador através de um código em formato binário: o op code. Assim, um programa é 
na realidade um conjunto de códigos binários, cada um correspondendo à determinada 
instrução. 
 
 
Programar em código de máquina, seja este em binário ou hexadecimal, é chamado de 
programação em linguagem de máquina. 
Como tais códigos são de difícil manipulação, os fabricantes de processadores colocam 
um nome para cada instrução. Este nome é chamado de mnemônico. A programação 
através de mnemônicos é conhecida por linguagem Assembly 
 
 Assembly 
 
Na realidade, a linguagem Assembly é muito semelhante à linguagem de máquina, só 
diferindo da utilização de nomes ao invés de códigos. Como são linguagens que envolvem 
um conhecimento muito profundo do processador e são distantes da linguagem formal 
utilizada por nós humanos, são conhecidas por linguagens de baixo nível. 
 
Todas as demais linguagens existentes são denominadas linguagens de alto nível, pois 
estão mais próximas da linguagem humana. Mas tais linguagens não são entendidas pelo 
processador. Até mesmo a linguagem Assembly não é entendida pelo processador, que só 
reconhece a linguagem de máquina, os op codes. 
Daí, temos a necessidade de transforma a linguagem de alto nível ou Assembly, o código-
fonte (o programa), em linguagem de máquina. 
Em alguns casos existe a figura do interpretador, que lê códigos intermediários, 
resultantes de uma compilação e executa rotinas (pequenos trechos de programa) em 
código de máquina. 
 Assembly 
 
Transformar um código fonte em um arquivo executável – que contenha op 
codes – é um processo chamado compilação. A compilação é feita por 
uma aplicação chamada compilador. Existem milhares de compiladores, 
que devem ser compatíveis com a linguagem de alto nível utilizada e o 
sistema operacional/processador em questão. 
 
Quando o código fonte está em linguagem Assembly, utilizamos um 
compilador especial, denominado Assembler. O Assembler tem uma 
tarefa mais simples que os demais compiladores, pois basicamente 
transforma mnemônicos em op codes. O Assembler depende do 
processador que estamos trabalhando e também do sistema operacional. 
 Transformando de alto nível para linguagem de máquina 
 
Algumas linguagens 
passam para uma 
linguagem intermediária 
(compilação) e depois 
interpretam o código 
intermediário, 
executando, depois, 
código de máquina. 
São os casos de Java 
(javabeans+JRE) e C# 
(MSIL+.NET Framework). 
 
 Instruções 
 
Conforme o processador, as instruções são agrupadas conforme sua função. Assim, em 
processadores Intel 8086/88, as instruções são divididas nos seguintes grupos e 
subgrupos: 
 Instruções 
 
A partir do Pentium MMX, a Intel criou a IA-32, sigla da arquitetura interna destes 
processadores, e dividiu as instruções em uma outra forma, conforme o tipo de dado: 
 Exemplo de instrução 
 
Instrução MOV 
 
Sintaxe: 
 
MOV op1, op2 
 
Onde op1 é o operando destino e op2 é o operando fonte. 
 
MOV copia o dado contido no operando fonte para o operando destino. O operando op2 
pode ser um dado, um registrador ou uma posição de memória. Op1 poderá ser um 
registrador ou uma posição de memória. Alguns tipos de movimentação não são validos, 
tais como mover um valor diretamente para um registrador de segmento ou copiar o 
conteúdo de um endereço de memória para outro diretamente. 
O op code da instrução MOV varia conforme os operandos utilizados. 
 Exemplo de instrução 
 
Exemplos: 
 
MOV AH,01 Coloca no registrador AH o valor 01 (byte – 8 bits) 
MOV BX,1234h Coloca em BX o valor 1234h 
MOV ECX,11223344h Coloca em ECX o valor 1223344h 
MOV AX,BX Copia o conteúdo de BX em AX 
MOV DS,AX Copia o conteúdo de AX em DS 
MOV [8000h],AL Coloca no endereço DS:8000h o conteúdo de AL (não apaga o 
 conteúdo em AL ) 
MOV [BX],AH Coloca o conteúdo de AH no endereço de memória indicado por 
 DS:BX 
 
 Exemplo de instrução 
 
 
Exemplos não válidos: 
 
 
 MOV SS,5000h Não é válido !!!!!! Não pode movimentar valores diretamente 
 para registradores de segmento 
 
MOV AL,BX Não válido!!! Não se pode copiar um conteúdo de 16 bits para 
 um registrador de 8 bits. 
 
MOV [0002h],1 Não válido!!! Não dá para definir se o operando 1 é um byte ou 
 uma word. 
 Op codes gerados 
 
Note que o op code varia de instrução para 
instrução, conforme, no caso de MOV, dos 
operandos envolvidos. 
Cada instrução MOV do exemplo ao lado 
resultou em 3 bytes de código, sendo 1 byte 
de op code e 2 bytes de operando. Note que o 
operando está invertido, pois o processador 
trabalha desta forma: primeiro armazena a 
parte baixa, depois armazena a parte alta. 
Já a instrução int 3, apesar de ter um 
operando, resultou em apenas 1 byte de op 
code. 
 
 
 Ciclo Buscar-Decodificar-Executar 
 
Quando desejamos executar um programa, informamos através do Sistema Operacional 
qual programa desejamos executar e onde está tal programa. O programa, caso seja um 
código executável, é um conjunto de instruções, que é carregado para um área da 
memória especificada pelo Sistema Operacional. Veja o esquema: 
 
 
 Ciclo Buscar-Decodificar-Executar 
 
O sistema operacional recebe um comando – o nome do programa e sua localização, por 
exemplo; O Sistema operacional, que também é um programa que está sendo executado, 
faz com que o processador atue nos dispositivos de E/S – como por exemplo, o disco rígido 
– informando para transferir todo o programa para uma determinada área da memória. 
A partir daí o Sistema Operacional informa ao processador para saltar para o endereço da 
1ª instrução do programa carregado na memória – um desvio – carregando os devidos 
endereços em CS:IP. 
 
Um arquivo executável é composto por instruções em linguagem de máquina, que por sua 
vez são representadas pelos op codes. Basta então que o processador acesse estas 
instruções na memória, interpreta-as e realize as operações necessárias, continuando o 
processo (indo para os endereços seguintes) até o fim do programa. A este ciclo damos o 
nome de ciclo buscar-decodificar-executar. Tal ciclo se repetirá para cada instrução do 
programa. 
 
 
 
 Ciclo Buscar-Decodificar-Executar 
 
 
A primeira parte do ciclo – buscar – consiste no processador dispor de um 
endereço de memória que indique onde está a instrução a ser buscada. 
Este endereço será indicado por CS:IP, que é enviado à BIU (Unidade de 
Interfaceamento de Barramento). A BIU acessa a memória, recebendo no 
barramento de dados o op code da instrução. ] 
O código recebido é testado por uma unidade e, se for apenas um dado, é 
enviado para um registrador especificado pelo processador. Se for uma 
instrução, o código é encaminhado para a Fila de Instrução. 
O ponteiro CS:IP é incrementado para buscar um outro código. Todo este 
ciclo é executado pela Prefetch Unit do processador. 
 
 
 
 Ciclo Buscar-Decodificar-Executar 
 
 
 
 
 
 Ciclo Buscar-Decodificar-Executar 
 
 
O ciclo decodificar é realizado pela Unidade de Decodificação de 
Instrução. 
Esta unidade busca na Fila de Instruções o opcode e envia à um circuito 
que irá comparar tal código com uma tabela, trocando-o por uma série de 
microcódigos, os quais são devolvidos à unidade de execução para serem 
executados. Como tal tabela é uma espécie de software gravado no 
hardware (processador), ela também é conhecida por Firmware. 
 
Quanto mais instruções o processador tem em seu set de instruções, maior 
e mais complexo é este Firmware. 
 
 
 
 Ciclo Buscar-Decodificar-Executar 
 
Após o ciclo decodificar vem o ciclo executar. O ciclo executar é feito pela Unidade de Execução. 
Esta unidade recebe os microcódigos e realiza as operações indicadas por estes. Basicamente, o que 
o processador pode executar resume-se nas seguintes operações: 
 
a) Registradores: a operação consiste em ler o conteúdo de um determinado registrador ou 
armazenar um dado em um registrador. Quem define o registrador é o processador, conforme os 
microcódigos recebidos. 
 
b) Desvio: tal operação é um desvio no fluxo de execução do programa, consistindo em alterar o CS 
e/ou IP. 
 
c) Cálculo: a operação é um cálculo. O processador informa a ALU – Unidade Lógico Aritmética – o 
que deseja e os dados que serão processados pela ALU. 
 
d) Acesso à Memória ou E/S: a operação é de acesso a memória ou um dispositivo de E/S (porta de 
E/S). O processador informa à BIU e envia os dados e endereços necessários à esta. 
 
 
 
 
 Pipeline 
 
Observamos no capítulo anterior, a seqüência buscar-decodificar-executar. A princípio 
parece ser um mecanismo eficiente, inclusive por contar com unidades que trabalham 
separadamente, cada qual com uma tarefa distinta. Porém, tal processo não é eficaz. 
No momento em que o processador está executando uma operação, não está ocorrendo 
nenhuma atividade na busca de um novo código, nem na decodificação de outros op 
codes. O processador necessitaria que a execução da instrução termine para poder iniciar 
todo um novo ciclo. Isto é considerado desperdício de tempo: enquanto uma unidade está 
trabalhando, as outras estão paradas. 
 
Para que tal desperdício de tempo não ocorra é que existe a técnica de pipeline: todas as 
partes do ciclo buscar-decodificar-executar, funcionando ao mesmo tempo. Isto significa 
que enquanto a unidade de execução está trabalhando, há um outro op-code sendo 
decodificado e uma outra instrução sendo buscada, tudo ao mesmo tempo. Há um 
paralelismo interno. 
 
 
 
 
 
 Pipeline 
 
Há mudanças internas no processador para que ele execute este paralelismo.Em 
comparação com o esquema anterior, notamos a seguinte diferença: a unidade de 
decodificação e execução foi desmembrada. Agora, a unidade de decodificação de 
instrução busca o op code na fila, chamada corretamente de Prefetch Queue. O op code 
é enviado para a tabela de micro códigos, sendo traduzido. Os micro códigos são enviados 
para uma outra fila, chamada de Instruction Queue. 
Dalí, são buscados pela Unidade de Execução, que efetua as operações. E o mais 
importante: todas estas unidades funcionam ao mesmo tempo, aumentando a 
performance do processador. 
Apesar do tempo de execução da instrução não ser alterado pelo pipeline, o programa 
como um todo tem um ganho significativo de tempo, pois enquanto uma instrução está 
sendo executada, outra já está sendo buscada, e outra decodificada. 
 
 
 
 
 Pipeline 
 
 
 
 
 
 Superescalaridade 
 
Em um processador superescalar, a Unidade de Execução é dividida em várias partes. 
Aliás, verdadeiramente, a divisão acontece na ALU (Unidade Lógico-Aritmética), que 
agora dividida, tem o poder de realizar mais de uma operação aritmética por ciclo. O 
Intel Pentium foi o 1° processador da Intel a contar com a superescalaridade. Sua Unidade 
Lógico-Aritmética era capaz de processar um cálculo com números inteiros, outro cálculo 
com números de ponto flutuante e ainda calcular um endereço de desvio, tudo ao mesmo 
tempo. E para agilizar ainda mais o processo, a Instruction Queue, que contém os micro 
códigos a serem executados, também é desmembrada, tendo agora uma fila para 
operações com ponto flutuante, outra para números inteiros e outra para desvio, para que 
a fila não fique “congestionada” no caso de existir uma seqüência de um só tipo de 
cálculo. 
 
 Os atuais processadores contam com um número maior de unidades de execução para 
diferentes tipos de execução 
 
 
 
 
 Superescalaridade 
 
 
 
 
 
 Execução dinâmica 
 
A Partir do Pentium Pro, a Intel implementou algo inovador: um mecanismo de “execução 
fora-de-ordem” (out-of order execution) denominado Execução Dinâmica. 
 
A Execução Dinâmica compreende três conceitos de processamento de dados: 
 
 Previsão profunda de saltos; 
 Análise dinâmica do fluxo de dados; 
 Execução especulativa. 
 
Tais conceitos foram implementados para melhorar a performance do processador, sendo 
hoje considerados fundamentais em processadores de alta performance. 
 
 
 
 
 Previsão de salto 
 
Como a técnica de pipeline consiste em executar várias partes do ciclo buscar-decodificar-executar 
ao mesmo tempo, a Prefetch Queue está sempre cheia, e o processador sempre está executando 
uma instrução. Sendo superescalar, isto ocorre mais rápido. 
Agora, suponha o seguinte programa: 
 
1B79:0100 8B1E0000 MOV BX,[0000] 
1B79:0104 8B07 MOV AX,[BX] 
1B79:0106 50 PUSH AX 
1B79:0107 EB07 JMP 0110 
1B79:0109 43 INC BX 
1B79:010A 8B0F MOV CX,[BX] 
1B79:010C 90 NOP 
1B79:010D 51 PUSH CX 
1B79:010E 43 INC BX 
1B79:010F 43 INC BX 
1B79:0110 83C302 ADD BX,02 
1B79:0113 8B07 MOV AX,[BX] 
1B79:0115 50 PUSH AX 
 
 
 
 
 Previsão de salto 
 
As instruções são buscadas e colocadas na prefetch queue na seguinte ordem: 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Previsão de salto 
 
Segundo o conceito de pipeline, tais instruções foram buscadas, 
decodificadas e executadas. 
Até a 3a instrução tudo ocorre normalmente. Porém, ao executar a 4ª 
instrução, que é um desvio incondicional para o offset 0110h, o 
processador deve se desviar para tal offset. A 5ª, 6ª, 7ª e assim por diante, 
instruções, buscadas e decodificadas não serão executadas: o processador 
“perdeu tempo” buscando e decodificando estas instruções, quando o que 
seria considerado correto era começar a buscar a partir do offset 0110h e 
assim por diante. Mas o processador não sabia que a 4ª instrução era um 
desvio. Com o mecanismo de previsão de saltos, as instruções seriam 
executadas “fora-de-ordem” de que se encontram na fila. Mas como o 
processador iria “adivinhar o salto” antes de ele ser executado? 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Previsão de salto 
 
Agora, antes da Prefetch Queue há a 
Unidade de Execução Especulativa, que, 
conhecendo de antemão o op code das 
instruções de desvio, já executa o desvio 
antecipadamente, fazendo com que, no 
ciclo de busca seguinte, o processador 
busque os códigos já no endereço correto. 
Com isso, não há perda de tempo: sempre 
se estará buscando e decodificando as 
instruções na ordem correta de execução, 
fora da ordem que estão na memória. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Análise dinâmica do fluxo de dados 
 
Em um processador superescalar, tem-se um ponto ideal de desempenho quando todas as 
unidadesde execução (ponto flutuante e inteiros) estejam “cheias”, isto é, processando. 
 
Porém, conforme o fluxo do programa, pode ser que determinada unidade esteja 
sobrecarregada e outra vazia, fazendo com que o desempenho do processador não seja o 
melhor possível. 
 
A análise dinâmica de fluxo de dados envolve uma análise do fluxo do programa em 
tempo real, das instruções que passam pelo processador. A unidade de execução 
dinâmica, baseada em informações da unidade de execução determina certas pendências 
de dados e conteúdos de registradores que poderiam atrasar o processamento, 
detectando oportunidades de executar algumas instruções fora de ordem, para elevar a 
performance de processamento, pois a execução fora de ordem coloca uma ordem que 
não venha causar dependências de resultados, deixando as unidades de execução 
permanentemente ocupadas. 
 
 
 
 
 
 
 
 
 
 
 
 
 Execução especulativa 
 
Observe o código de programa a seguir. No offset 0108h temos um desvio condicional. E 
aí surge a seguinte dúvida: e se o processador executar antecipadamente este salto? 
Como ele saberá se é para executar ou não, já que ele se baseia em uma condição 
(AX=FFFFh)? Deixar de buscar antecipadamente as instruções ou antecipar a busca como 
se o desvio condicional fosse ser executado poderia resultar em perda de tempo em 
ambos os casos. 
 
 
 
 
 
 
 
 
 
 
 
 
 Execução especulativa 
 
 
É neste ponto que entra a execução especulativa. Se a análise dinâmica 
de fluxo de dados não resolver o problema, a unidade de execução 
especulativa irá calcular uma estatística da probabilidade deste desvio 
condicional ser executado e, baseado neste dado, executará o desvio um 
determinado número de vezes. Isto pode dar errado, pois não há como o 
processador acertar em 100% dos casos, mas na maior parte o processador 
acerta, poupando tempo e diminuindo o tempo de processamento.

Outros materiais