Você está na página 1de 90

1

ARQUITETURA E
ORGANIZAÇÃO DE COMPUTADORES
2

ARQUITETURA E
ORGANIZAÇÃO DE COMPUTADORES
U 1 - POR ONDE COMEÇAR PARA
ENTENDER COMO O
COMPUTADOR FUNCIONA?
Ednaldo dos Santos

Introdução

Neste capítulo, vamos estudar os conceitos mais fundamentais, relacionados ao


funcionamento do computador, e compreender como ocorreu a evolução técnica até chegar os
computadores que conhecemos atualmente. Estes conceitos são importantes para que se
conheça, posteriormente, elementos mais aprofundados a respeito do computador como um
todo e a sua interoperabilidade com o Sistema Operacional.

Para começar esse percurso, você vai se deparar com a diferenciação entre dois níveis de
abstrações, que podemos associar aos sistemas computacionais: a arquitetura e a organização.
Para entender essa diferenciação vamos nos perguntar: o que é família de processadores?

Também veremos um histórico dos principais computadores projetados até os dias atuais,
correlacionando-os com a própria evolução da eletrônica. E, para concluir, apresentaremos os
conceitos inerentes ao pipeline e à superescalaridade, para que você possa refletir sobre as
seguintes questões: o que influencia na performance de processamento de um computador?
Como poderemos aumentar o poder de processamento de um sistema computacional?

A partir dos conceitos aqui apresentados, você terá condições de se situar na trajetória dos
sistemas computacionais e aplicar seu conhecimento no seu cotidiano, seja na tomada de
decisões, ou na aplicação no desenvolvimento de aplicações.

Vamos acompanhar com atenção? Bons estudos!

1.1 Visã o geral da arquitetura e organizaçã o de


computadores

Muito se fala em família de processadores, principalmente quando estamos


escolhendo um Sistema Operacional ou um aplicativo a ser instalado no
computador. Mas, o que vem a ser uma família, dentro do mundo dos
computadores? Para que se possa responder a essa pergunta, devemos, antes,
responder a outra pergunta: o que vem a ser arquitetura e organização de
computadores?
Esse tópico ajudará você a encontrar a resposta, ao compreender os detalhes mais
evidentes para um programador, em relação à construção do processador, e
3

aqueles que não são muito importantes, pelo menos, a princípio. Apesar de menos
importantes, esses detalhes devem ser de conhecimento do programador, em
algumas situações, para que se possa alcançar um nível maior de eficiência
computacional, diminuindo-se o tempo de processamento pela otimização de seu
código para um processador específico.
Então, a partir de agora, vamos entender como se organizam os computadores, por
meio de sua arquitetura.

1.1.1 Arquitetura e organização de computadores

Vamos fazer uma analogia da noção de arquitetura e organização de computadores


com a implementação de uma função no âmbito de programação. Uma função tem
o seu protótipo (tipo de retorno e a lista de parâmetros) e a parte da implementação
com o seu respectivo código (instruções). Quando uma biblioteca de funções é
utilizada, o programador precisa apenas se preocupar em como passar os
parâmetros e como coletar o seu resultado. Dessa forma, não é necessário saber
como a função foi implementada.
Assim ocorre também nos computadores: há uma separação das características e
estruturas importantes, para que se possa construir aplicativos, compiladores,
sistemas operacionais e todos os demais softwares que rodarão sobre um
processador específico. Sabendo disso, podemos exemplificar como elementos da
arquitetura de computadores (STALLINGS, 2010):

• conjunto de instruções: conhecer quais instruções exportadas pelo


processador são indispensáveis para, por exemplo, os projetistas de
compiladores, para que seja possível realizar a tradução das instruções
escritas em uma linguagem de alto ou médio nível (por exemplo, C/C++)
para a linguagem de máquina (assembly);
• mecanismos de Entrada e Saída (E/S) (I/O – Input/ Output): o
programador deve saber como proceder para que o seu programa possa
interagir com dispositivos externos, como escrever um driver que leia e
envie informações via USB (Universal Serial Bus);
• técnicas de endereçamento: neste caso, podemos citar como deve ser
implementada a parte do Sistema Operacional que manipula o
gerenciamento da memória;
• tamanho dos tipos de dados: refere-se ao tamanho do espaço de memória
(quantidade de bytes) necessário para armazenar uma variável de um certo
tipo (char, int, float, por exemplo). Neste caso, o programador deverá ter
conhecimento do tamanho e, consequentemente, dos tipos de dados
disponíveis para escolher o mais apropriado para o seu programa.

Por outro lado, o termo ‘organização de computadores’ refere-se aos aspectos


internos de projeto e implementação de um processador, que não são fundamentais
ao programador. Dentre os itens relacionados à organização, podemos citar:

• sinais internos de controle: podem ser entendidos como pulsos elétricos,


ativados pela execução de uma instrução, responsáveis pela ativação e
sincronização dos módulos de hardware;
4

• forma de implementação das instruções: por exemplo, uma subtração é


realizada com um circuito específico de subtração, ou é implementada com
o circuito de adição, somando-se o inverso da seguinte forma: a = b – c →
a = b + (-b)?;
• hierarquia dos módulos funcionais: como os sub-módulos de hardware
estão organizados dentro do processador e como são as suas ligações
elétricas?

Agora, você pode estar se perguntando: qual a relação entre arquitetura e


organização de computadores com o termo ‘família de processadores’? Então,
vamos entender isso melhor.
Uma família relaciona processadores que possuem a mesma arquitetura. Então,
pode-se afirmar, por exemplo, que todos os processadores da família x86 possuem
o mesmo conjunto de instruções, mesma forma de endereçamento e mesmo
espaço de memória para os tipos disponíveis de dados. É por esse motivo que
você consegue executar o mesmo programa em um computador com um
processador da Intel e também em um outro com um processador da AMD, sem a
necessidade de se realizar qualquer alteração na programação ou recompilar o
código. Isso porque, neste exemplo, ambos os processadores pertencem à família
x86.
Vamos, então, entender como o computador é estruturado e suas funcionalidades.

1.1.2 Estrutura e função

Ao nos aprofundar na organização de computadores, podemos pensar o


computador como sendo a interconexão entre os módulos internos de hardware.
Esses módulos poderão, ainda, ser subdivididos. A cada aprofundamento em suas
camadas, teremos módulos mais simples e especializados. O nome dessa
estruturação física em módulos funcionais é estrutura. Uma possível abstração de
estrutura computacional é exibida na figura a seguir.
5

Deslize sobre a imagem para Zoom

Figura 1 - Estrutura de um computador em sua abstraçã o de alto nível e a decomposiçã o do processador em


submó dulos pela aplicaçã o da metodologia top-down. Fonte: STALLINGS, 2010, p. 10.

A figura acima utiliza uma abordagem denominada como “top-down” para descrever
os módulos internos. Ao contrário da “bottom-up”, na metodologia “top-down”,
partese dos módulos mais gerais e superiores para que estes sejam decompostos
em submódulos, até que se alcancem módulos que não precisem ser subdivididos,
devido à sua simplicidade e funcionalidade bem determinada.
Observe novamente a figura anterior e perceba que, no primeiro nível de abstração,
o computador é formado pelos seguintes módulos primários (STALLINGS, 2010):

• CPU: módulo responsável pelo processamento propriamente dito. Cada


instrução do programa é carregada para a CPU, a fim de ser decodificada e
executada;
• memória principal: na memória principal são alocados espaços para que
possam ser carregados os processos (programas em execução). Sendo
assim, na memória principal, encontramos instruções, dados e informações
de controle de processamento;
• E/S (Entrada/ Saída): entidades responsáveis por realizar a interação com
o “mundo externo” para coletar ou externar informações. São exemplos de
módulos de E/S: controladores de teclado, de vídeo, HD (Hard Disk), etc.;
• Barramento do Sistema: elemento responsável por realizar a interconexão
dos demais módulos. Os módulos são distribuídos seguindo uma
organização física denominada como topologia.

Por sua vez, a CPU é decomposta pelos submódulos:

• registradores: representam a memória interna do processador, para que


sejam carregadas as instruções e as informações a serem manipuladas;
• ALU (Arithmetic Logic Unit, em inglês, traduzido como Unidade Lógica e
Aritmética, ULA): tem a responsabilidade de executar operações
aritméticas (como uma adição) e operações lógicas (como comparação de
magnitude);
• Barramento Interno: módulo cujo objetivo é permitir a interconexão entre
os demais módulos, permitindo-se um fluxo de informações entre eles;
6

• Unidade de Controle: gerencia o fluxo de informações internamente ao


processador, sendo, também, responsável pela gerenciamento do
processamento em si.

Um outro conceito que podemos mencionar é denominado ‘função’. Como o próprio


nome indica, função representa as funcionalidades associadas a cada módulo que
integra o computador. Essencialmente, as funções do computador podem ser
agrupadas em quatro grupos básicos, conforme indica a figura a seguir.

Deslize sobre a imagem para Zoom

Figura 2 - Ao verificar as funçõ es bá sicas de um computador, percebemos que o mó dulo responsável pela
funcionalidade ‘Controle’ centraliza todas as operaçõ es. Fonte: STALLINGS, 2010, p. 4.

Na figura acima, notamos que a funcionalidade básica de controle gerencia as


demais funcionalidades, estabelecendo a interface entre os módulos ativados para
a execução das atividades correspondentes. Além da funcionalidade de controle,
encontramos a funcionalidade de processamento, cuja missão é executar as
instruções que manipularão as informações coletadas do mundo externo (por meio
dos módulos de E/S como, por exemplo, o ‘disco rígido’ ou, ainda, por uma rede de
comunicação de dados).
O processo de coleta ou de envio das informações para o mundo externo
representa a funcionalidade de movimentação. Por fim, temos a funcionalidade
de armazenamento, cujo objetivo consiste em guardar, em módulos de memória,
as informações oriundas do mundo externo ou derivadas do processamento. Agora,
você pode estar se perguntando: mas, como o computador, em sua funcionalidade
de controle, sabe quais módulos ativar?
7

O módulo de controle realiza sua tarefa em função das instruções obtidas do


programa sob execução. Cada instrução é decodificada para que o módulo de
controle saiba qual funcionalidade deve ser atingida naquele momento e,
consequentemente, quais módulos deverão ser ativados, alocando os recursos
necessários.
Agora, que você sabe o que é arquitetura e organização, estrutura e função, vamos
dar uma olhada na evolução dos computadores? Podemos observar que a
arquitetura e organização dos computadores estão associadas com a própria
evolução técnica que os computadores tiveram. Você pode aproveitar a deixa e
refletir sobre estrutura e função, correlacionando-as com a evolução dos
computadores.

1.2 Histó rico e evoluçã o dos computadores

Ao observar os computadores atuais, podemos dizer que eles evoluíram junto com
a eletrônica, desde o tempo das válvulas termiônicas até os atuais circuitos
integrados (chips).
Com a miniaturização do componentes, foi possível construir circuitos mais
complexos em espaços muito menores do que se usava anteriormente. Com os
componentes menores, a construção de memórias com mais capacidade e mais
rápidas, também se tornou possível, o que garante informações processadas de
forma mais eficiente. As novas tecnologias também permitem o emprego de
frequências maiores de operação, dissipando menos potência.
Além dos fatores físicos, novas técnicas de processamento, como o emprego de
pipeline, superescalaridade e execução fora de ordem, vem permitindo o aumento
da performance de processamento.
Então, vamos ver como se sucederam as gerações dos computadores, com um
breve histórico da evolução dos computadores, para que você possa tirar suas
próprias conclusões sobre arquitetura e organização, e do quanto evoluímos nos
aspectos tecnológicos.

A matemática e escritora inglesa Ada Lovelace foi a primeira pessoa a escrever um algoritmo para
computador. Em sua homenagem, foi atribuído o seu nome à uma linguagem de programação. A
linguagem Ada foi criada em 1982, teve como base o Cobol e o Basic e foi referência para a criação da
linguagem de programação Ruby (PORTAL EBC). Saiba mais na
matéria: <http://www.ebc.com.br/tecnologia/2015/03/conheca-historia-da-ada-lovelace-
primeiraprogramadora-do-mundo>.

A partir de agora, vamos observar que a evolução das gerações dos computadores
terá inúmeras consequências, não somente no impacto positivo do poderio de
processamento, quanto também nas funcionalidades exportadas pelos
processadores. Sob o ponto de vista da programação, a evolução pode ser
percebida pela forma de interação e programação, passando da programação pela
atuação direta de chaves e fios, até as linguagens atuais de quarta geração.
8

1.2.1 Primeira geração


Essa geração foi marcada pelo emprego das válvulas termiônicas em sua
construção. O pioneiro dos computadores foi o ENIAC (Electronic Numerical
Integrator and Computer), construído entre os anos de 1943 e 1946 pela
Universidade da Pensilvânia pelo físico John Mauchly e pelo engenheiro John
Eckert.
O ENIAC foi construído com o intuito de realizar cálculos balísticos para o BRL
(Ballistic Research Laboratory, laboratório do exército dos Estados Unidos) para que
fosse utilizado durante a Segunda Guerra Mundial. Apesar de não ter sido
finalizado a tempo de entrar em operação durante a guerra, teve, como primeira
missão, cálculos para a construção da bomba de hidrogênio.
O ENIAC operava segundo um sistema decimal de numeração (não era binário) e
tinha a capacidade de processar 5000 adições por segundo. Porém, para que
fossem usadas as suas 30 toneladas, em suas 18 mil válvulas, era necessária a
configuração contínua de chaves e de cabos (conectando-os e desconectando-os)
para denotar as operações e as informações a serem processadas. Tudo isso era
feito manualmente por seis programadoras do exército, especialistas em cálculos
balísticos.
O ENIAC tem um merecido destaque, pois foi o primeiro computador eletrônico
construído para uso genérico. Porém, em função da dificuldade de sua
manipulação, pode-se dizer que, em termos de estruturação, o destaque da
primeira geração fica a cargo do EDVAC (Electronic Discrete Variable Automatic
Computer) e, um pouco depois, do IAS (Institute for Advanced Studies, da
Universidade de Princeton), projetado pelo matemático John von Neumann, nos
anos de 1946 e 1952, respectivamente.
A ideia de von Neumann consistia no emprego de memória para o armazenamento
do programa. Isso tornava mais fácil a interação com o computador para a
programação. A figura a seguir, ilustra a concepção proposta por von Neumann no
IAS.
9

Deslize sobre a imagem para Zoom

Figura 3 - Estruturaçã o do IAS com os elementos encontrados nos computadores atuais: programa armazenado em
memó ria, ULA, unidade de controle e E/S. Fonte: STALLINGS, 2010, p. 14.

Na figura acima podemos encontrar, como módulos básicos:

• Memória Principal: memória utilizada para armazenar, instruções e dados


a serem processados, ou resultantes do processamento. As instruções são
formadas por palavras binárias, interpretadas diretamente pelo hardware;
• Unidade Lógica-Aritmética (ULA): módulo responsável por realizar as
operações aritméticas e lógicas do computador;
• Unidade de Controle (UC): a partir das instruções coletadas da memória, a
UC tem a missão de decodificá-las e providenciar a sua execução;
• equipamento de E/S: interface entre o computador e o mundo externo.

Podemos observar que alguns conceitos e estruturas desenvolvidos no IAS ainda


tem significado para os computadores atuais. Inicialmente, foi usado o termo
‘palavra’ para designar a unidade básica de armazenamento e transferência (no
caso, a palavra era de 40 bits). Também foi utilizado o termo ‘registrador’ para
denotar estruturas de armazenamento internamente à ULA ou à unidade de
controle (STALLINGS, 2010):

• Registrador de Buffer de Memória (MBR, Memory Buffer Register): usado


para armazenar ou receber uma palavra da memória ou da unidade de E/S;
• Registrador de Endereço de Memória (MAR, Memory Address Register):
armazena o endereço de memória que contém a informação a ser enviada
ao MBR ou o endereço de memória que receberá a informação presente no
MBR;
• Registrador de Instrução (IR, Instruction Register): contém a palavra
referente à instrução em execução;
• Registrador de Buffer de Instrução (IBR, Instruction Buffer Register):
mantém a próxima instrução a ser executada;
10

• Contador de Programa (PC, Program Counter): indica o endereço de


memória da próxima instrução a ser executada;
• Acumulador e Quociente-Multiplicador (AC e MQ, respectivamente):
armazena operandos e resultados provenientes da ULA.

Por fim, o conjunto do IAS tinha 21 instruções, agrupadas de acordo com as suas
funcionalidades: transferência de dados (entre memória e registrador ou
registradorregistrador), desvio incondicional, desvio condicional, aritméticas e
modificação de endereço (para permitir um endereçamento flexível).

O matemático Alan Turing é considerado como o pai da computação. Desenvolveu várias teorias, que
culminaram na criação da Inteligência Artificial e que contribuíram na criação do computador como
conhecemos atualmente. Quanto à criação do computador, ele teve, simultaneamente a von Neumann, a
mesma ideia do programa armazenado em memória para que pudesse ser processado (NUNES, 2012).

Após conhecer essas informações sobre o IAS, podemos comparar quais os


elementos presentes no IAS que são encontrados nos computadores atuais.
Certamente, é uma reflexão interessante de se fazer.
Finalizando a primeira geração, podemos destacar os momentos importantes
(STALLINGS, 2010):

• 1947 – fundação da Eckert-Mauchly Computer: UNIVAC;


• 1952 – IBM: implementação do computador modelo 700;
• 1953 – IBM: implementação do computador modelo 701;
• 1955 – IBM: implementação do computador modelo 702.

A seguir, vamos acompanhar um breve histórico da segunda geração de


computadores.

1.2.2 Segunda geração

A segunda geração teve seu início a partir da substituição de válvulas por


transistores, que, além de serem menores, consumiam menos energia, o que
ampliou a eficiência computacional e possibilitou desenvolver memórias com maior
capacidade de armazenamento (STALLINGS, 2010). Essa substituição foi possível
em um contexto no qual vários pesquisadores buscavam inovações no campo das
telecomunicações, até que, em 1948, o físico William Shockley, desenvolveu o
transistor de junção, no laboratório Bell Labs.
O transistor é feito com materiais denominados semicondutores, formados pela
adição de impurezas ao silício, por exemplo. Essa adição permite que sejam
criados semicondutores do tipo P (positivo) e do tipo N (negativo). Essa diferença
de carga permite o controle do fluxo de elétrons – base dos circuitos eletrônicos.
11

Como unidades de memória, mencionamos o aparecimento dos núcleos de ferrite,


fitas e tambores magnéticos como dispositivos de memória.
Além das alterações físicas (hardware), essa geração foi marcada com o
aparecimento de linguagens de programação de alto nível, como Fortran e Cobol, e
pelas aplicações administrativas, gerenciais e comerciais.
Em relação ao gerenciamento dos computadores, essa geração também foi
marcada pelo aparecimento dos primeiros sistemas operacionais com a função de
sequenciar automaticamente as tarefas, apenas, por esse motivo, eles eram
chamados de “monitor”. Assim, desta segunda geração, podemos destacar os
seguintes momentos (STALLINGS 2010):

• 1957 – fundação da companhia Digital Equipment Corporation (DEC): PDP-


1 (início da geração de minicomputadores);
• 1960 – IBM: modelo 7090;
• 1962 – IBM: modelo 7094 I; • 1964 – IBM: modelo 7094 II.

Dos modelos implementados pela IBM, o 7094 merece destaque, pois introduziu
um processador dedicado às operações de E/S (Entrada/ Saída), como veremos na
figura a seguir. Nelas, o processador principal envia um sinal de controle ao
processador de E/S (canal de dados), que fica responsável por realizar a
transferência das informações. Após o término da operação, o canal de dados
emite um sinal ao processador principal para que ele processe os dados recém
transferidos. Dessa forma, ocorre uma liberação de processamento do processador
principal. Esta técnica era conhecida como “buffering”.

Deslize sobre a imagem para Zoom

Figura 4 - Estruturaçã o do IBM, modelo 7094, no qual se pode notar a presença de vá rios mó dulos de E/S
compartilhando o acesso à CPU e à memó ria. Fonte: STALLINGS, 2010, p. 21.
12

Observe que na figura acima, há um módulo “multiplexador”. Multiplexador é um


componente que permite selecionar um canal para que somente um dispositivo
possa, em um determinado tempo, enviar ou receber informações do processador.

1.2.3 Terceira geração

Os computadores iniciais da segunda geração tinham na ordem de 10 mil


transistores em sua implementação. Mas, a partir da implementação de circuitos
integrados (1958), esse número teve um aumento muito expressivo chegando a
centenas de milhares na terceira geração. A partir disso, podemos destacar nesta
geração (SILBERSCHATZ; GALVIN; GAGNE, 2015):

• o aparecimento das memórias baseadas em semicondutores e discos


magnéticos: a partir desta geração, passou-se a utilizar componentes
baseados em semicondutores (silício, por exemplo) para a fabricação de
memória. Além dos semicondutores, o sistema de memória também foi
contemplado com os discos magnéticos (memória secundária);
• a criação da técnica de spool (Simultaneous Peripheral Operation On-Line):
ao invés dos canais de dados serem manipulados de forma multiplexada,
como na segunda geração, a manipulação dos dispositivos de E/S passou
a ser simultânea;
• evolução dos sistemas operacionais com o aparecimento da
multiprogramação: essa técnica consiste em compartilhar o
processamento entre vários programas abertos. A execução dos
programas se dá de forma alternada. Para que o processador não seja
monopolizado, um certo programa é executado durante uma fatia de
tempo (chamada como time slice) ou até ser provocado um evento de E/S.
Quando um desses fatos ocorrer, o programa em questão deixa de alocar
o processador para que um outro programa o aloque, repetindo-se o
processo. Essa alternância é gerenciada pelo Sistema Operacional por
meio do escalonador de processos.

Devido ao escalonamento pelo tempo, a multiprogramação é também denominada


como “tempo compartilhado” (figura a seguir). Com essa ideia, surgiram alguns
sistemas operacionais como o CTSS/MIT, que proporcionou o aparecimento do
MULTICS, que evoluiu para o UNIX. Na figura a seguir, temos a execução de três
processos (P0, P1 e P2) concorrendo ao uso do processador.
13

Deslize sobre a imagem para Zoom

Figura 5 - Neste escalonamento, os trê s processos concorrem ao acesso à CPU, poré m, apenas um, de cada vez, é
detentor do recurso. Fonte: elaborada pelo autor, 2018.

Voltando ao histórico, um marco que se destacou nesta geração foi o lançamento


da linha IBM System 360, em 1964.
Para este lançamento, a estratégia da IBM foi lançar modelos distintos de
computadores dentro do linha 360, criando, então, a família 360. Os computadores
desta família eram compatíveis em relação ao código das aplicações desenvolvidas
e rodavam o mesmo Sistema Operacional (OS 360). Os computadores da família
360 diferenciavam apenas em relação aos custos, tamanho da memória, número
de canais de dados e performance de processamento (SILBERSCHATZ; GALVIN;
GAGNE, 2015).
Você poderia, agora, traçar um paralelo entre a ideia de família 360 e a família x86
que temos atualmente? O que se mantém nesses computadores da mesma
família? Por fim, não poderíamos deixar de citar, dentro desta geração, o
lançamento do DEC
PDP-8 no mesmo ano de lançamento do IBM 360. O diferencial entre os dois
modelos é que a DEC continuou estimulada a produzir minicomputadores para
ganhar espaço em um segmento de mercado não coberto pela IBM: o de baixo
custo (US$ 16 mil do PDP-8 contra centenas de milhares de dólares do IBM 360).

O termo OEM (Original Equipment Manufacturers) é utilizado quando um módulo (por


exemplo, um circuito ou dispositivo) é criado por uma empresa para que possa fazer
parte do produto de final de outra empresa. Você sabia que essa ideia foi concebida
pela DEC em seu computador PDP-8 na década de 1960?

Para finalizar, também não poderíamos deixar de mencionar que a DEC lançou, em seu PDP-8, a
ideia de barramento para interconectar os módulos do computador. A ideia deste barramento, o
“Omnibus”, deu origem aos barramentos que conhecemos atualmente equipando os
microcomputadores.

1.2.4 Quarta geração


14

A quarta geração está vinculada à alta escala de integração dos transistores dentro dos circuitos
integrados. Na ULSI (Ultra Large Scale Integration) temos mais de um milhão de transistores, dentro de
um mesmo chip. Essa redução drástica do espaço ocupado pelos componentes eletrônicos propiciou o
aparecimento dos microprocessadores e multiprocessadores.

Em 1965, o co-fundador da Intel, Gordon Moore, anunciou a profecia de que a capacidade (e o número de
transistores) de um processador dobraria, mantendo-se o custo. Essa profecia se tornou verdade e,
atualmente, é considerada como a “Lei de Moore”. Ainda não se sabe até quando essa lei será mantida
como verdade (MARKOFF, 2016). Leia mais na matéria do New York Times, que mostra que a lei de
Moore ainda é um desafio: <http://www1.folha.uol.com.br/tec/2016/05/1768028-lei-de-moore-esta-se-
esgotandoe-tecnologia-busca-sucessores.shtml>.

O alto fator de integração possibilitou a introdução de técnicas mais agressivas de


processamento no que diz respeito à performance computacional e a gama de
funcionalidades. As técnicas presentes nos computadores atuais têm como foco
garantir a alta disponibilidade das informações e do processamento. Para
exemplificar esse foco, podemos citar o pipeline e a superescalaridade.
Em relação aos softwares, podemos mencionar o surgimento de linguagens de
programação como C++, SQL, JAVA, assim como os sistemas operacionais de rede
e distribuídos.

1.3 Projetando e visando ao desempenho


Do ponto de vista da computação podemos perguntar: o hardware, em relação ao
seu desempenho, tem que acompanhar as novas aplicações que exigem cada vez
mais recursos, ou as aplicações cada vez mais complexas aproveitam dos recursos
oferecidos pelos novos equipamentos?
Independentemente da resposta, o que se sabe é que o poderio dos processadores
e dos computadores, como um todo, sofre uma contínua evolução frente ao seu
desempenho. Um outro ponto merece ser instigado: como se ganha tanta
performance se os conceitos usados ainda hoje, provém do modelo proposto por
von Neumann em sua máquina IAS?
Como resposta inicial, podemos dizer que a evolução tecnológica provida pela
miniaturização dos componentes (estamos na era da nanoeletrônica, pois os
componentes estão na casa dos nanômetros) permite que circuitos mais complexos
sejam implementados, ocupando o mesmo espaço físico. Uma outra questão é que
os sinais, em circuitos muito menores, apresentam um tempo de propagação
menor, pois as distâncias a serem percorridas são igualmente menores.
Porém, além do avanço da eletrônica, a melhoria de desempenho é alcançado por
intermédio da introdução de novas técnicas e metodologias de processamento.
Como técnicas adicionais, além das representadas pelo paralelismo encontrado
nos processadores, podemos citar (STALLINGS, 2010):
15

• previsão de desvio: caso nenhuma técnica fosse utilizada, ao se deparar


com uma instrução que contenha um desvio (do tipo ‘if...else’ ou um laço de
repetição), o processador ficaria a esperar pelo resultado da expressão
associada para que tomasse a decisão de qual linha a ser executada. Na
previsão de desvio, é criada uma tabela que contém o resultado do desvio
(desvio tomado ou não tomado). Cada linha da tabela correspondente aos
bits menos significativos dos endereço de memória (localização da
instrução). Com base nesta tabela de histórico, o processador tenta
antecipar o início da próxima instrução. Caso tenha tomado a decisão
errada, nenhum impacto de atraso será inserido no processamento pois
será como o processador ficasse esperando pelo resultado da condição do
desvio. Caso tenha acertado na previsão, então economizou-se o tempo de
espera pelo resultado da condição do desvio;
• análise do fluxo de dados: na análise de fluxo, observamos as instruções
em relação a suas dependências quanto à disponibilidade de recursos de
hardware e de dados. Neste caso, pode haver uma execução fora de ordem
quando a instrução apta a ser executada não corresponde à próxima
imediata na sequência;
• execução especulativa: representa a fusão da previsão de desvio com a
análise de fluxo, de forma a tentar antecipar ao máximo o início da próxima
instrução para manter o pipeline cheio.

1.3.1 Balanço ao desempenho

Caso sejam colocados dois processadores com frequências de clock diferentes,


qual o mais eficiente? Aquele que apresenta a maior frequência de clock? A
resposta não é bem essa. Para se decidir qual o melhor, deve-se realizar uma
análise não somente do processador mas, também, de todo o conjunto.
Balanço computacional refere-se a atenuar os gargalos que afetam a performance
na execução das instruções. Por exemplo, não basta o processador atuar em uma
frequência extremamente grande, se a memória não for capaz de fornecer-lhe as
informações com a eficiência necessária.
Quanto à memória, algumas técnicas poderão ser utilizadas para diminuir a
diferença de desempenho entre a memória e o processador. Vamos entender a
seguir (STALLINGS, 2010).

• Aumentar a largura de transferência entre a memória e o processador:


um dos grandes vilões para a performance de processamento é o
barramento – canal por onde passam as informações vinculadas aos
dispositivos de E/S e à própria memória. Aumentando-se a largura de
transferência, com uma única requisição, é possível a transferência de um
conjunto maior de bits. Com isso evitamos que o tráfego de sinais de
sincronização de barramento e de endereços impacte negativamente na
taxa de eficiência de transmissão do barramento. Uma outra técnica para
evitar gargalos de transferência entre memória e processador consiste em
criar um barramento exclusivo entre essas duas entidades. • Introdução
de caches mais eficientes ou mais próximas ao nó de processamento: a
memória cache evita o acesso frequente à memória principal (MP). O
acesso à MP tem dois pontos negativos em relação ao acesso à cache: a
16

tecnologia empregada na MP é mais lenta em relação à cache e quanto


mais longe o módulo de memória estiver do núcleo de processamento,
maior será a latência de tempo, devido ao maior percurso que o sinal
deverá percorrer.
• Aumentar o número de portos de leitura e escrita da memória: quando
se opera com paralelismo no processamento das instruções, a
probabilidade de se ter duas requisições para a utilização da memória é
alta. Nesta situação, caso a memória tenha apenas um porto de
leitura/escrita, umas das instruções ficaria bloqueada até o término da
outra. Para se evitar esse problema, é necessário dotar a memória de dois
portos (canais) de leitura/escrita para que ambas as instruções possam
acessá-la simultaneamente.
• Melhoria do desempenho dos dispositivos de E/S: de nada adianta
aumentar o poderio do processador, da memória e dos barramentos, se os
dispositivos de E/S continuarem a ser um gargalo para a performance
computacional. Diante disso, além da preocupação em se construir
dispositivos mais eficientes, técnicas de otimização do tratamento das
requisições e de cache (em nível das unidades de controle de cada
dispositivo de E/S) vêm sendo implantadas.

Você sabia que, para reduzir o tráfego de endereços e de sinais de controle, a


memória trabalha no modo “rajada” (burst)? Neste modo de operação, a memória
poderá enviar informações cujas localizações (endereços) sejam consecutivas ao
endereço de uma solicitação anterior. O artigo no portal “Clube do Hardware”
(TORRES, 2016), menciona esse aspecto:
<https://www.clubedohardware.com.br/artigos/memoria/tudo-o-quevoc%C3%AA-
precisa-saber-sobre-as-temporiza%C3%A7%C3%B5es-dasmem%C3%B3rias-ram-
r34433/?nbcpage=3>.

Além dos investimentos dos sistemas de memória, barramentos e dispositivos de


E/S, muito se tem investido para se ter processadores cada vez mais poderosos e
eficientes, principalmente para aumentar o fator de integração de seus
componentes (em nível de transistores) ou seja, na adoção de técnicas de
processamento mais agressivas. Como duas principais técnicas, temos o pipeline e
a superescalaridade.

1.3.2 Pipeline e superescalaridade

Como dito anteriormente, pipeline e superescalaridade são técnicas, baseadas na


execução paralela das instruções, que visam o aumento da performance dos
sistemas computacionais.
O ponto chave do pipeline é tentar antecipar o início da próxima instrução. Mas,
como fazer isso? Para começar, vamos falar que, para se alcançar um melhor
resultado, uma instrução pode ser decomposta em várias microinstruções
(STALLINGS, 2010). Para uma melhor abstração, vamos imaginar uma sequência
17

para calcular a ação de um jogador no futebol de robôs, composta de quatro


etapas:

1) obter uma imagem que representa a situação atual do campo da partida; 2)


decodificar a imagem para que se possa gerar as posições de todos os jogares e
da bola (por exemplo, no formato de coordenadas cartesianas);
3) diante do posicionamento dos robôs do próprio time e do adversário, gerar uma
estratégia de ação;
4) colocar em prática a estratégia gerada com a ativação da movimentação dos
robôs.
Para tanto, vamos imaginar, inicialmente, que as etapas citadas sejam executadas
sequencialmente, e para se iniciar o processamento de uma imagem temos que
finalizar, totalmente, o processamento da imagem anterior (desde a coleta da
imagem até a movimentação dos robôs). Essa abstração sequencial é ilustrada na
figura abaixo, item (a).

Em um segundo momento, imagina-se que cada etapa seja executada por um


hardware específico. Dessa forma, o resultado de uma etapa, assim que for
finalizada, será encaminhado para a etapa seguinte. O hardware que passou a
informação para o módulo seguinte, ao invés de ficar ocioso, começa a atuar no
processamento da próxima informação. O item (b) da figura a seguir, mostra
exatamente essa antecipação do processamento da imagem seguinte.

Deslize sobre a imagem para Zoom

Figura 6 - Diferenças entre o tempo de processamento sequencial (a) e com pipeline (b). Fonte: Elaborada pelo
autor, 2018.

Na figura acima, em (b), percebemos que a antecipação do início da próxima etapa,


conseguida pela divisão da ação em etapas, fez com que, mesmo não diminuindo o
tempo para processar uma imagem (definida na figura com o termo “img”),
18

conseguiu-se uma redução no tempo de processamento de um conjunto de


imagens. No caso exemplificado, para se processar três imagens, passou-se de 12
para apenas seis unidades de tempo.

Você sabia que você pode usar essa abstração de pipeline também em nível de
software? Para tanto, basta implementar o seu programa usando threads. As threads
são funções do seu programa que se comportarão como se fossem programas
independentes – porém usando o mesmo espaço de endereçamento (por exemplo,
podendo acessar as mesmas variáveis globais). Para saber mais sobre programação
usando threads, você poderá procurar pela biblioteca pthread (POSIX threads).

Para finalizar, devemos saber que, além de implementar a técnica de pipeline, um


processador pode ser, também, superescalar. A superescalaridade consiste em se
replicar unidades funcionais de processamento para que se possa processar duas
ou mais instruções simultaneamente, ou seja, de forma paralela.

1.4. Evoluçã o das arquiteturas

Atualmente, o cenário mundial dos processadores está polarizado entre dois


mercados: o representado pelos computadores pessoais e o representado pelos
sistemas embarcados (também chamados por sistemas embutidos).
No âmbito dos computadores pessoais, encontramos computadores baseados em
processadores da família x86 e, em relação aos sistemas embarcados,
processadores ARM (Advanced RISC Machine).
Vamos conhecer cada um deles a seguir.

1.4.1 Intel x86

A família x86 é muito importância para o mundo dos sistemas computacionais, não
somente pela sua ampla utilização mas, também, por implantar vários aspectos
tecnológicos nos projetos de seus processadores.

No momento de seu lançamento, na década de 1980, o processador da Intel 8086 tinha, como
principal concorrente, o Motorola MC68000, que equipava os Apple Macintosh. Eles se
diferenciavam completamente, tanto em relação à arquitetura quanto à organização. Como
exemplo, podemos citar a largura dos registradores: o processador da Intel tinha registradores de 16
bits e o modelo da Motorola manipulava registradores de 32 bits. Em linhas gerais, o 68000 era mais
desejável pelos programadores do que o 8086. Mas, se o modelo da Motorola é mais desejável e
eficiente, porque o mercado atualmente é dominado por processadores derivados do Intel 8086? A
19

resposta baseia-se em estratégia de mercado. A Intel permitiu que qualquer fabricante de


computadores pudesse usar o seu processador sem pagar direitos (royalties), enquanto que a
Motorola não tinha esse modelo de negócio. Diante dessa possibilidade das indústrias produzirem
clones e placas-mãe baseadas no 8086 sem ter a necessidade de pagar os direitos fez com o
mercado apresentasse um crescimento muito rápido da utilização da plataforma da Intel. Com isso,
a Intel conseguiu fazer que o seu modelo dominasse o mercado, que ainda hoje é consequência
desta estratégia mercadológica.

Durante a evolução da família x86, podemos destacar os pontos principais


(STALLINGS, 2010):

• 8080: primeiro microprocessador de uso geral; caminho de dados de


8 bits;
• 8086: contém 29 mil transistores; 16 bits; cache de instruções (pré-busca
das instruções);
• 80386: suporte para multitarefa; 32 bits;
• 80486: cache evoluída para dados e instruções; presença de pipeline;
coprocessador matemático embutido;
• Pentium: organização superescalar;
• Pentium Pro: superescalaridade aumentada; renomeamento de
registradores; previsão de desvio; execução especulativa;
• Pentium II: incorporação de tecnologia MMX (para manipulação de
informações multimídia);
• Core: primeiro x86 com dual core;
• Core 2: arquitetura de 64 bits;
• Core 2 Quad: 820 milhões de transistores; quatro processadores no chip.

Nos processadores atuais, como o Intel Core-i7, comenta-se a existência de processadores (ou núcleos)
lógicos (ou virtuais) e físicos. Mas, o que vem a ser isso? Recomendamos um artigo (TELES, 2009) que
descreve a arquitetura do i7, desde o gerenciamento de memória até a descrição de núcleos virtuais e
físicos: <http://www.ic.unicamp.br/~ducatte/mo401/1s2009/T2/042348-t2.pdf>.

Atualmente, novas pesquisas vem sendo desenvolvidas para que ataque, de forma
ainda mais agressiva, o paralelismo internamente ao processador. Processadores
com mais núcleos (tanto físicos quanto virtuais) estão sendo lançados no mercado,
possibilitando o paralelismo em vários níveis de abstração.

1.4.2 Sistemas embarcados e ARM

Um sistema embarcado é aquele que apresenta a combinação entre software e


hardware, para executar um objetivo dedicado. Geralmente falamos que um
sistema computacional é dedicado, quando ele desempenha apenas um tipo de
funcionalidade, por exemplo, controlar um dispositivo tendo em vista os dados
20

coletados por meio de sensoriamento. Aos sistemas embarcados, geralmente


associamos condições limites como (STALLINGS, 2010):

• pequena quantidade de memória disponível para conter o programa e suas


variáveis;
• limitação na dissipação de potência e, portanto, no consumo de energia;
• condições ambientais agressivas, como vibrações, altas amplitudes
térmicas;
• geralmente associados com manipulação de sinais analógicos provenientes
de sensores e interfaceados por conversores A/D (analógicodigital) e
enviados para atuadores por intermédio de conversores D/A (digital-
analógico);
• não se limita a um processador por sistema embarcado: um único sistema
embarcado pode conter, além do processador, outros elementos de
processamento, tais como: DSP (Digital Signal Processor), FPGA (Field
Programmable Gate Array) e circuitos do tipo ASIC (Application Specific
Integrated Circuit).

A figura abaixo mostra as funcionalidades que podemos encontrar nos sistemas


embarcados.

Deslize sobre a imagem para Zoom

Figura 7 - Funcionalidades bá sicas que podemos encontrar em sistemas embarcados, que podem possuir vá rios nó s
de processamento. Fonte: Fonte: STALLINGS, 2010, p. 37.
21

Sabemos que grande parte dos sistemas embarcados é equipada com


processadores ARM, então, vamos conhecer algumas de suas características
básicas (STALLINGS, 2010):

• projetado pela ARM Inc., Cambridge, Inglaterra. Projetos posteriores feitos


em conjunto entre a Acorn, Apple, VLSI Technology. Atualmente,
processadores ARM licenciados para que sejam construídos por diversas
empresas, como Cirrus Logic, Texas Instruments, ATMEL, Samsung,
Nvidia, Sharp, Qualcomm;
• alta velocidade, baixos requisitos de potência;
• encontrado em PDAs, jogos portáteis, telefones, freios ABS e aplicações
que envolvem tempo real;
• suporta sistemas operacionais como Linux, Linux, Palm OS, Symbian OS,
Windows Mobile.

Como você pode ter notado, desde o primeiro computador eletrônico até os
modelos atuais, houve um grande salto, tanto da tecnologia eletrônica quanto dos
métodos e algoritmos usados para acelerar ainda mais o poder computacional.
Com o que aprendemos até aqui, podemos refletir sobre até quando será válida a
Lei de Moore e quais serão as próximas inovações na informática, como alguns dos
questionamentos atuais desse campo de estudo.

Síntese
Chegamos ao final deste capítulo. Vimos aqui os conceitos iniciais importantes para começar a
entender o funcionamento do computador. Nestes conceitos, estão presentes a definição de como o
computador está organizado, em sua arquitetura e organização, assim como realizar a

diferenciação entre estrutura e função.

Com os pontos aqui apresentados, esperamos que você prossiga os estudos relacionados ao
funcionamento do computador e possa fazer comparações iniciais entre modelos de máquinas
dentro de um processo de consultoria técnica, por exemplo.

Neste capítulo, você teve a oportunidade de:


• compreender as diferenças entre arquitetura e organização, de modo a
poder reconhecer e comparar famílias de processadores; listar as
funcionalidades de um processador relacionando-as com as estruturas
internas, representadas pelos submódulos de hardware;
• visualizar os computadores em função de seu contexto histórico, podendo
aplicar os conceitos inerentes a cada geração de computadores às
características dos computadores atuais;
• identificar os pontos que impactam no desempenho de processamento de
um computador, assim como analisar e formular solução para a sua
melhoria.
22

Projeto

A HISTÓRIA DOS COMPUTADORES E O PROFISSIONAL DE


TI

O computador é um equipamento capaz de realizar uma grande


quantidade de tarefas, fazendo parte da vida das pessoas, facilitando
e dinamizando a realização dos trabalhos diários. É uma máquina
antiga, que foi aprimorada com o passar dos anos e aponta para o
futuro.

A história dos computadores, palavra que significa calcular, remonta a


Idade Antiga e, naquela época, eram representados pelos ábacos. Os
primeiros ábacos que se têm notícia existiram na antiga Suméria, no
período de 2.700 a 2.300 a. C., e foram criados para atender à
necessidade humana de manipular números.

Outra questão que envolve os computadores é que necessitam serem


programados, isto é, precisam receber instruções com formalismo
(regras) específico. As instruções são chamadas de algoritmos, que
são desenvolvidos pelos programadores.

Na Idade Moderna, em 1642, foi criado pelo cientista francês Blaise


Pascal o computador mecânico, chamado de máquina de calcular,
que funcionava por meio de engrenagens. O cientista criou o
equipamento com o objetivo de ajudar seu pai.

Os computadores com válvulas foram desenvolvidos durante a


Segunda Guerra Mundial, em que se destaca o COLOSSUS,
considerado o primeiro computador eletrônico digital do mundo. Ele
foi criado com o objetivo de decifrar rapidamente as mensagens
nazistas codificadas, evitando-se, assim, a morte de muitos soldados.
23

Mais tarde, em 1965, as válvulas foram substituídas pelos circuitos


integrados, surgindo, então, uma nova fase para os computadores,
que tiveram seu tamanho diminuído, redução no consumo de energia
e aumento da capacidade de processamento.

Posteriormente, os circuitos integrados evoluíram para os very large


scale integration – integração em escala muito grande,
aumentandose, então, a eficiência dos equipamentos. Durante os
anos 1980 e início dos anos 1990, alguns modelos de computadores
tornaram-se menores, surgindo os dispositivos móveis, tecnologia
que evoluiu e vem sendo muito utilizada.

Atualmente, os computadores estão integrados à vida das pessoas,


sendo utilizados na área da saúde, educação, segurança etc.,
possuindo capacidade, tamanho e formas variados. No mundo
moderno, o computador busca atender à necessidade das pessoas,
surgindo, a todo instante, novas tecnologias inovadoras, que são bem
aceitas pelas pessoas e pelo mercado empresarial.

Uma dessas tecnologias é o Honeycomb Glacier (computador com tela


adicional), um computador portátil, um notebook com duas telas,
sendo uma principal e outra secundária, possuindo ainda o teclado.

Trata-se de um equipamento direcionado para o mercado de jogos,


em que o jogador acompanha o jogo na tela principal, tendo à sua
disposição os controles na tela secundária e o teclado. A grande
vantagem é que a usabilidade dos controles dos jogos ficou mais
simples, ou seja, o jogador consegue ativar comando a partir do
toque na segunda tela.

Outro computador bem interessante, de alto desempenho e


atualizável, é o notebook Alienware Area-51m, da Dell, que possui um
visual bem interessante e aceita upgrade. Esse equipamento possui
um processador de desktop Intel Core i9- 9900HK de oito núcleos e
uma placa de vídeo Nvidia GeForce RTX 2080.
24

As inovações não são apenas na área de jogos, muito pelo contrário: a


Intel está preparando tecnologias capazes de suportar grande cargas
de dados, como é o caso das Memórias Persistentes Intel® Optane™
DC. Elas são projetadas para funcionar em supercomputadores e
suportar a carga de trabalho.

Outra questão importante a se considerar é a convergência de


tecnologia, qual seja, a utilização de tecnologia de inteligência artificial
com a computação de alto desempenho.

Com relação à inteligência artificial, a Intel está lançando


processadores específicos para trabalhar com os dados ainda na
fonte ou mesmo para aprendizado de redes neurais, demonstrando
uma nova tendência para o futuro.

Todas essas inovações e o caminho que o mercado tecnológico está


traçando para o futuro tornam-se extremamente necessárias para a
atuação do profissional de TI, que deverá possuir conhecimentos
multidisciplinares e, acima de tudo, conhecer a estrutura
computacional conforme a realidade de cada empresa.

O profissional de TI deverá garantir que os equipamentos apresentem


o máximo desempenho possível. Esse ganho de eficiência fará com
que as empresas reduzam os custos operacionais, aumentando
eficiência, produtividade e, consequentemente, gerando mais postos
de trabalho.

Vamos praticar

Faça um texto crítico, em uma lauda, que retrate a criação e a evolução dos computadores, o
surgimento de tecnologias como Honeycomb Glacier (computador com tela adicional), os
equipamentos de alto desempenho e atualizável, como o notebook área 51, os processadores
de alto desempenho da Intel que auxiliarão a definir o futuro da computação, e a importância
do profissional de TI conhecer a estrutura computacional conforme as necessidades da
organização (desempenho computacional).
25

No seu texto, você deverá discorrer sobre a importância do conhecimento de hardware para o
mercado de trabalho atual, efetuando uma breve pesquisa sobre as inovações tecnológicas.

ARQUITETURA E ORGANIZAÇÃO DE
COMPUTADORES
U 2 - COMO O COMPUTADOR MANIPULA
INSTRUÇÕES E INFORMAÇÕES?

Ednaldo dos Santos

Introdução
Com a quantidade de informações com que lidamos atualmente, sem o computador, não seria
possível nem encontrar utilidade para tantos dados. Ao aprofundar nossos conhecimentos em
arquitetura e organização de computadores, vamos entender como o computador se estrutura,
segundo uma visão de alto nível, para que possamos mergulhar em seus elementos de
interconexão, na estrutura e função do processador.

Diante disso, já nos deparamos com algumas reflexões: o processador precisa fornecer as
instruções e os dados para os seus módulos internos a fim de que haja o processamento?
Nesse sentido, como armazená-los internamente de modo que não tenhamos de acessar a
memória em toda a etapa da execução da instrução? E, ainda, como uma instrução fica
representada na memória?

Já que iremos tratar os aspectos inerentes às funcionalidades do processador e representação


de instruções, por que não falarmos também sobre as etapas de execução da instrução dentro
de um ambiente dotado de pipeline?

Mas, como você deve ter notado, toda forma de armazenamento e manipulação de dados e de
instruções é realizada por intermédio de valores numéricos. E como representar e manipular os
números em seu formato binário? Vamos entender isso também.

E, por fim, falaremos sobre a unidade de controle e os seus sinais de controle, – sinais estes
indispensáveis à sincronização e ao gerenciamento dos módulos do processador.

Vamos entender melhor o funcionamento do computador, por meio da organização e das


funcionalidades exportadas pelo processador. Além disso, com os pontos-chave aqui expostos,
você poderá otimizar as aplicações a serem desenvolvidas por você em função da adequação
ao modelo computacional adotado como plataforma.

Está pronto para começar esse percurso de descobertas? Bons estudos!


26

2.1 Introduçã o à arquitetura de computadores

Para entender como o computador funciona, precisamos, antes, conhecer a sua


organização e as funcionalidades de seus módulos. Com isso, será possível não
somente entendermos, mas, também, propormos soluções de desenvolvimento de
sistemas mais otimizados – aproveitando-se as particularidades de um sistema
computacional. A seguir, vamos compreender melhor de que maneira os
computadores manipulam as instruções e informações por ele processadas, além
de descobrir como o computador é estruturado, para que, em seguida, possamos
detalhar os seus elementos.

2.1.1 Visão de alto nível do computador

Inicialmente, é conveniente lembrar que, em relação aos computadores ditos como


pessoais, seguimos o modelo do matemático John von Neumann (TANENBAUM,
2013). Nesse modelo, a filosofia básica de trabalho consiste no programa
armazenado em uma estrutura de memória para que possa ser executado pelo
processador. Além da memória, como elementos de sua organização, podemos
encontrar a unidade de controle e a unidade lógica e aritmética.
Diante da herança frente ao modelo de von Neumann (TANENBAUM, 2013),
podese dizer que os elementos básicos de um sistema computacional são
(STALLINGS, 2010):

• sistema de memória: dividido, ainda, em memória secundária (por


exemplo, os HDs – Hard Disks), memória principal, memória cache e
registradores (memória interna dos processadores);
• unidade de processamento: dentro do processador, encontramos a
unidade de controle, a unidade lógica e aritmética, a rede de interconexão
interna e os registradores (para o armazenamento de instruções, dados e
informações de controle);
• unidades de E/S (Entrada/Saída): objetiva o interfaceamento com os
dispositivos de entrada e de saída;
• rede de interconexão: tem a função de interconectar os módulos
pertencentes ao sistema computacional.

Além dos módulos em si, precisamos ter em mente que, para que eles atuem, é
necessária toda uma sincronização de trabalho. Essa sincronização é atingida pela
geração de sinais de controle, os quais estão presentes dentro do processador para
que este possa executar as instruções, e, também, estão presentes nos demais
módulos que integram o computador.
Nesse sentido, conhecer os módulos do computador e a sua forma de trabalho é
fundamental para que você possa saber, entre outras questões, quais são os
pontos de gargalos de processamento. Esse conhecimento permitirá que você
otimize os sistemas a serem desenvolvidos ou, ainda, reconfigure o computador
para que sua performance computacional se torne mais eficiente.
27

2.1.2 Interconexão do computador, estrutura e função do


processador

Antes de entrarmos especificamente no processador, vamos detalhar um pouco


mais os elementos do sistema computacional, destacando a sua interconexão. A
figura a seguir ilustra os módulos e a sua interconexão.

Deslize sobre a imagem para Zoom

Figura 1 - Mó dulos bá sicos de um computador e sua interconexã o, em que é possível notar a presença do
barramento do sistema para prover a interconexã o dos mó dulos. Fonte: STALLINGS, 2010, p. 55.

Na figura acima, você pode notar a presença de canais de comunicação


interrelacionando os módulos do sistema computacional. Tais canais transportam
informações envolvendo os dispositivos de E/S (interfaceados via buffers) além de
transportarem dados e instruções entre a memória e o processador. Por sua vez,
internamente à CPU são apresentados, além da unidade de execução,
registradores de controle – os quais você verá mais adiante.
A estrutura apresentada na figura anterior permite que o processador desempenhe
a sua função básica: executar instruções. Para que uma instrução seja executada,
é necessário que esta seja carregada da memória para o processador. Sendo
assim, para executar um programa completo, o processador deverá, em suma,
realizar a busca da instrução e executá-la – linha a linha de código.
A execução representa o envio de informação e a ativação de módulos específicos,
correspondentes a cada classe de instrução. Geralmente, os processadores
manipulam quatro classes de instruções, enumeradas a seguir (STALLINGS, 2010):
28

• processador-memória: representa as instruções de transferência de dados


entre o processador e a memória;
• processador-E/S: ao invés da transferência de informações envolvendo a
memória, as instruções do processador-E/S intercambiam informações
entre o processador e os módulos de E/S;
• processamento: compreende as instruções que realizam a execução
propriamente dita. As informações a serem manipuladas deverão estar,
necessariamente, carregadas nos registradores do processador;
• controle: as instruções de controle estão relacionadas aos desvios
condicionais e não condicionais, alterando, dessa forma, a sequência do
fluxo de processamento das instruções.

Como mencionado anteriormente, as instruções precisam, para que sejam


decodificadas e executadas, estar carregadas nos registradores do processador.
No entanto, cabe a questão: como as instruções ficam alocadas na memória do
computador? Para responder a essa pergunta, vamos adentrar em aspectos de
organização de registradores para que possamos compreender o ciclo da instrução.

2.2 Organizaçã o dos registradores

Como mencionado, todas as instruções e informações a serem processadas


deverão, necessariamente, ser carregadas previamente no processador. Para
tanto, o processador possui um conjunto de registradores de uso geral (GPR –
General Purpose Registers) e um conjunto de registradores para que sejam usados no
controle do processamento.

2.2.1 Registradores visíveis ao usuário: uso geral e dados

Registradores do tipo GPR têm a função de armazenar as informações sob


processamento. Por exemplo, caso seja necessário executar uma operação de
soma do tipo C = A + B, os valores de A e B deverão ser carregados previamente
da memória e armazenados em registradores. Após o processo de execução ser
completado, o resultado deverá ser armazenado também em registradores. Você
pode estar se perguntando se o fato de ter que carregar sempre, antes, em
registradores não consome mais tempo de processamento. Primeiramente,
podemos afirmar que quando as informações estão presentes em registradores, a
chance de serem reaproveitadas em outras instruções próximas é alta. Sendo
assim, os compiladores possuem estratégias de otimização para que se possa
aproveitar ao máximo os valores previamente carregados nos registradores.
Um segundo aspecto refere-se à organização do hardware. Por exemplo, em
computadores do tipo RISC (Reduced Instruction Set Computer), as operações que
manipulam informações são do tipo registrador-registrador, ou seja, as fontes são
oriundas de registradores e o resultado é salvo também em registrador
(STALLINGS, 2010). Dessa forma, os circuitos internos de interfaceamento tornam-
29

se mais simples e, consequentemente, não é necessário um módulo de seleção da


fonte (chaveandose entre a memória e o banco de registradores).

Você sabia que alguns processadores, como o registrador zero, apresentam um valor
fixo em 0 (zero)? Essa escolha é motivada pelo fato de que a frequência de aparição
de instruções do tipo carga do valor 0 (instanciação de dados com o valor zero) é alta.
Dessa forma, economiza-se o tempo de carga da constante já que o valor zero já se
encontra internamente ao processador, bastando, para tal, realizar uma
movimentação de dados do tipo registrador-registrador (por exemplo, Reg1 = Reg0).

Para finalizar essa seção, como exemplo prático, convém mencionarmos que o
processador Intel Core i7, apresenta, em cada núcleo, 16 registradores GPR
(General Purpose Register) em seu banco de registradores (TELES, 2018).

2.2.2 Registradores de estado e de controle

Além dos registradores do tipo GPR, o processador mantém um conjunto de


registradores destinados ao armazenamento de códigos de estado e de valores de
configuração.
Na figura anterior, é possível encontrar alguns exemplos de registradores desse
tipo, tais como os listados a seguir (STALLINGS, 2010):

• PC (program counter): o registrador PC, também chamado como IP


(instruction pointer), armazena o valor de endereço que contém a próxima
linha de código (instrução) a ser executada. A cada busca de instrução, o
valor de PC é incrementado para que, no próximo ciclo, seja executada a
instrução subsequente. Em instruções de desvio, o PC pode receber o
valor do endereço que contempla a instrução após o salto (desvio);
• IR (instruction register): como você já está sabendo, para que a instrução
possa ser executada, ela precisa ser carregada para dentro do
processador. O local para o armazenamento da palavra que contém a
instrução é o registrador IR. Com base no valor armazenado, o
processador realiza todas as etapas envolvidas na sua execução;
• MAR (memory address memory): o registrador de endereço de memória
contém o valor do endereço para o próximo acesso à memória. Com o uso
desse registrador, o processador informa, ao sistema de memória, o
endereço sobre o qual será realizado o acesso (para a leitura ou para a
escrita);
• MBR (memory buffer register): após o MAR configurado, ao efetivar o
acesso à memória, o item manipulado (gravado ou lido da memória) é
armazenado no MBR. Sendo assim, o MAR e o MBR fazem parte do
interfaceamento entre o processador e a memória;
• I/O AR (input-output address register): de forma análoga ao
interfaceamento entre processador e memória, existe o registrador I/O AR,
que contém o endereço do dispositivo de E/S a ser acessado; • I/O BR
30

(input-output buffer register): o item manipulado entre o processador e o


dispositivo de I/O é armazenado no registrador I/O BR.

Além dos registradores listados acima, não poderíamos deixar de citar o registrador
de flags. O registrador de flags é instanciado ao término, por exemplo, das
operações aritméticas a fim de armazenar o estado final da operação, bem como
informar se a operação resultou em algum valor negativo, nulo ou, ainda, se houve
estouro de representação numérica (overflow). Mas por que armazenar esse estado
final da operação? Vamos lhe dar um exemplo. Na maioria dos processadores, para
se fazer uma operação de desvio, é necessário testar exatamente esse registrador
de flags. A figura a seguir ilustra a tradução de um desvio condicional a partir de
uma linguagem de alto nível para um assembly (linguagem de máquina) hipotético.
Além dos registradores listados acima, não poderíamos deixar de citar o registrador
de flags. O registrador de flags é instanciado ao término, por exemplo, das
operações aritméticas a fim de armazenar o estado final da operação, bem como
informar se a operação resultou em algum valor negativo, nulo ou, ainda, se houve
estouro de representação numérica (overflow). Mas por que armazenar esse estado
final da operação? Vamos lhe dar um exemplo. Na maioria dos processadores, para
se fazer uma operação de desvio, é necessário testar exatamente esse registrador
de flags. A figura a seguir ilustra a tradução de um desvio condicional a partir de
uma linguagem de alto nível para um assembly (linguagem de máquina) hipotético.

Deslize sobre a imagem para Zoom


31

Figura 2 - Exemplo de traduçã o


de um trecho de có digo usando linguagem de alto nível (a) para um assembly hipoté tico (b) a fim de ilustrar o
registrador de flags. Fonte: Elaborada pelo autor, 2018.

Na parte (b) da figura acima, tem-se o código traduzido da parte (a) para o assembly
de uma máquina hipotética. Suponha que os valores das variáveis a e b já estejam
carregadas nos registradores reg1 e reg2, respectivamente. A linha um realiza a
subtração desses dois registradores e armazenando o resultado no registrador reg 3.
Além do cálculo em si, a instrução de subtração também instancia os campos do
registrador de flags. No nosso exemplo, daremos atenção ao campo S (sinal). Esse
campo será instanciado em um caso a instrução de subtração retorne um valor
negativo e, caso contrário, o campo será instanciado em zero. O campo S será
avaliado na instrução da linha dois: js (jump signal). Caso o campo S esteja
sinalizado em um (resultado negativo), o fluxo de execução do código será
desviado para o endereço apontado pelo rótulo parte_else (caso negativo, então,
significa que a < b). Caso contrário (S = 0), assim, o trecho identificado como
<sequência_if...> será executado.
Caso o fluxo tenha passado pela <sequência_if...>, a linha três, contendo um desvio
incondicional (jmp = jump) será responsável por saltar o trecho <sequência_else...>
para que o fluxo seja direcionado à primeira instrução fora do comando if... else
(<sequência_após_desvio...>).
Por fim, as linhas quatro e cinco representam os rótulos para nortear os desvios
junto às instruções de desvios condicionais e não condicionais.
32

Você sabia que é possível usar desvios não condicionais em linguagens como C/C+
+? Em disciplinas de programação, o desvio não condicional “goto” tem o seu uso
proibido. Porém, em algumas situações, torna-se necessário utilizá-lo. Por exemplo:
ao codificar programas para sistemas embarcados, em que se tem uma forte restrição
de memória (não se pode realizar muitas chamadas de funções para evitar estouro de
pilha – stack), às vezes, o goto é essencial. Não somente em sistemas embarcados
podemos encontrar o “goto” – por exemplo, basta ver a codificação do kernel do
Linux.

Cada família de processadores contém, em sua organização, o seu próprio


mapeamento de registradores. A quantidade de registradores influenciará o formato
com que as instruções são armazenadas na memória.

2.3 Ciclo de Instruçã o

Anteriormente, abordamos a arquitetura básica, as funcionalidades das instruções e


dos registradores. Mas, cabe a pergunta, como as instruções são efetivamente
executadas? Antes de detalharmos como as instruções são executadas, vamos ver,
antes, como elas são armazenadas na memória.
Vamos supor a operação de subtração codificada em assembly contida na figura
anterior: “sub reg3, reg1,reg2”. Para começarmos a falar sobre a representação,
lembre-se de que o computador armazena apenas números. Então, os dados são
números (inclusive os caracteres são representados pelo valor contido na tabela
ASCII) e as instruções não poderiam deixar de ser um valor numérico.
Cada instrução possui um código denominado opcode. Assim, é a partir do opcode
que o processador reconhece quais os módulos deverão ser ativados e

qual o caminho que aos dados deverão seguir dentro dele. A figura a seguir ilustra
um possível formato para a instrução de subtração.

Deslize sobre a imagem para Z

Figura 3 - Exemplo de formato de instruçã o de subtraçã o de um processador hipoté tico de 16 bits.

Na figura acima, supõe-se que a máquina hipotética em questão tem uma largura
de palavra de 16 bits, sendo que o seu banco de registradores engloba oito
registradores e possui 125 instruções em sua arquitetura de conjunto de instruções
(ISA – Instruction Set Architecture). Fazendo as contas rapidamente, chegamos à
conclusão de que serão necessários três bits (log28 = 3) para endereçar cada
registrador e mais sete bits para mapear as instruções (log2125 ≈ 7).
33

Então, para mapear “sub reg3, reg1,reg2”, atribuindo aleatoriamente (para fins de
ilustração) o valor 0110111 para o opcode da instrução de subtração, tem-se a
palavra: 0110111 011 001 010 (lembrando que 011(2) = 3(10); 001(2) = 1(10); 010(2) =
2(10)).
Cada classe de instrução tem o seu formato de representação dentro da palavra de
16 bits. Sendo assim, os campos podem variar de tamanho e de representação,
exceto o campo do opcode que, nesse caso, será mantido fixo (15 a nove bits).
O início do processo de execução da instrução consiste em sua busca a partir da
memória. Como mencionado antes, o processador coleta toda palavra da memória
(conjunto formado pelo opcode e seus operandos) e armazena no registrador IR,
para que as informações sejam encaminhadas aos submódulos ao longo de sua
organização. Nesse caso, existe um fluxo de informações e de sinais pelos
caminhos do processador – caminhos estes chamados de datapath.

Em certas situações, ao nos depararmos com um problema para o qual temos de ter uma solução que envolva
hardware, surgem algumas dúvidas para reflexão: que tipo de hardware usaremos? Qual
microcontrolador/microprocessador utilizar para a questão? Porém, algumas vezes, a aplicação é muito específica
e usar uma plataforma pronta não é muito adequado. Nesse caso, pode-se desenvolver o próprio processador –
que manipula o seu próprio conjunto de instruções, possui o seu próprio mapeamento de registradores e o seu
próprio fluxo de dados. Os pontos vistos neste capítulo ajudariam no projeto de esboçar o processador otimizado
para o problema. Para tanto, a implementação seria baseada na utilização de hardware reconfigurável (ou lógica
reconfigurável). E, para a implementação, seria usada alguma linguagem de descrição de hardware (HDL
– Hardware Description Language), tal com Verilog ou VHDL. Nessa situação, poderá ser implementado, ainda, o
sistema embarcado baseado na ideia de SoC (system on chip) onda há a integração do mundo do software e do
mundo de hardware na mesma FPGA (Field Programmable Gate Array, em português "Arranjo de Portas
Programáveis em Campo"). Em função da integração de hardware e software, as etapas de análise e projeto de
um SoC também serão particionadas, ou seja, uma frente do projeto se envolverá com o hardware e uma outra
frente se envolverá com o software – esse particionamento é chamado como CoDesign.

Os módulos e suas conexões, no datapath, são diagramados de acordo com as


fases de execução das instruções. De acordo com (TANENBAUM, 2013), a
execução de uma instrução poderá ser dividida nas seguintes etapas:

• busca, pelo processador, pela próxima instrução da memória e carrega no


registrador RI;
• incremento do registrador PC, de modo a ser preparada a busca pela
instrução subsequente (a modificação do valor de PC poderá ocorrer
posteriormente caso a instrução seja de desvio);
• codificação do tipo da instrução carregada;
• carregamento dos operandos nos registradores (caso necessário);
• execução da instrução e registro do resultado;
• retorno ao início para recomeçar o ciclo em relação à próxima instrução.
34

Essa sequência de execução de uma instrução poderá ser manipulada de forma


puramente sequencial ou, ainda, ser alvo de otimização de fluxo de processamento
através da aplicação da técnica de pipeline.

2.3.1 Buscar, ler e interromper


Até o momento, comentamos as etapas para a execução das instruções sem a
ocorrência de eventos externos. No entanto, você deve estar se perguntando: e as
interrupções de hardware e de software? O que acontece no fluxo quando há a
incidência de alguma interrupção? As interrupções causam um grande impacto na
execução dos processos, pois elas devem ser atendidas quase que prontamente.

Você sabia que existe uma interrupção que é chamada quando o computador fica
ocioso? E que existe outra que é ativada sempre que houver um pulso de clock? E
que no Linux é possível visualizar uma lista de interrupções listando o conteúdo da
pasta /proc/interrupts?

O impacto é causado pelo fato de que quando o sistema operacional escalona os


processos (interrupções são também tratadas como processos), deve haver a troca
de contexto. Trocar um contexto significa que é necessário salvar todas as
informações relevantes do processo (tais como o valor do registrador PC, as flags e
algumas outras informações) para que, depois, quando o processo voltar à ativa,
possa ser restaurado exatamente do mesmo ponto e com as mesmas
configurações vigentes no momento de sua interrupção (PATTERSON, 1998).

Em algumas ocasiões, é necessário implementar drivers (softwares que interfaceiam com o sistema
operacional para controlar dispositivos de E/S – acessar registradores internos, interrupções etc.). No
portal Labworks (2018) há material para leitura e exemplos de código para a construção de drivers. Seria
um bom começo caso você esteja interessado no assunto:
<https://e-labworks.com/treinamentos/drivers/source>.

A figura abaixo ilustra o tratamento das etapas de execução de uma instrução


envolvendo a manipulação de interrupções. Em (a) tem-se o esquema básico de
representação e em (b), um detalhamento das etapas propriamente ditas.
35

Deslize sobre a imagem para Zoom

Figura 4 - Sequência de etapas para execuçã o das instruçõ es com a manipulaçã o de interrupçõ es: em (a), a
representaçã o bá sica, e em (b), o detalhamento das açõ es. Fonte: STALLINGS, 2010, p. 62-363.

Na figura acima, nota-se que, após a execução de uma instrução ser completada,
verifica-se se há alguma interrupção enfileirada pendente a ser executada. Nesse
caso, ela entraria como um processo normal, ou seja, as instruções vinculadas ao
tratamento da interrupção entrariam no fluxo do pipeline.
Quando um fluxo de execução é adicionado ao pipeline, o que acontece quando
alguma outra interrupção ocorre? Quando esse cenário ocorre, temos duas
maneiras de realizar o tratamento: na primeira forma, assim que o tratamento da
interrupção for iniciado, poderemos desabilitar novas interrupções ou permitir que
as próprias interrupções sejam interrompidas para o atendimento de outras. A figura
abaixo mostra a diferença entre esses dois enfoques.
36

Deslize sobre a imagem para Zoom

Figura 5 - Tratamento de interrupçõ es com a desabilitaçã o de novas interrupçõ es (a) e tratamento de novas
interrupçõ es de forma aninhada (b). Fonte: STALLINGS, 2010, p. 65.

Em relação à figura acima, temos em (a) o tratamento de interrupções


sequencialmente. Nesse tipo de enfoque, ocorre a desabilitação de interrupções
para que as novas que ocorrerem sejam apenas enfileiradas, de modo que o
tratamento ocorra somente após o término da atual. Por sua vez, em (b), no
tratamento aninhado, uma interrupção poderá ser interrompida para que seja
tratada uma com maior prioridade.
Em ambos os casos (sequencial ou aninhado), ocorrerá a interrupção da execução
dos processos do usuário para que as interrupções sejam tratadas pelo pipeline.

2.3.2 Fluxo de dados e estratégia de pipeline

Até o momento, por vários momentos, citamos o termo pipeline, porém sem nos
aprofundarmos. Você deve estar se perguntando: como o pipeline consegue,
efetivamente, agir em um ambiente com interrupções, desvios e demais fatos que
podem degradar a eficiência computacional? Antes de respondermos a esse
37

questionamento, vamos mencionar, antes, um fato relacionado com o fluxo de


dados.
Para se executar uma instrução, tem-se que coletar as informações a serem
manipuladas. Nem sempre uma informação é buscada de forma imediata, ou seja,
às vezes é necessária mais de uma etapa para fazê-lo.
Pois bem, vamos relembrar alguns registradores de controle e estado do
processador: PC, MBR e MAR. Você deve estar lembrando que o interfaceamento
entre o processador e o sistema de memória é realizado pelos registradores MBR e
MAR. Então, como acessar a memória para que seja buscada a instrução na
posição apontada pelo registrador PC? A figura abaixo ilustra, em (a), esse
processo.

Deslize sobre a imagem para Zoom

Figura 6 - Fluxo de dados na busca da instruçã o (a), na busca de operandos usando endereçamento indireto (b) e no
ciclo de interrupçã o (c). Fonte: STALLINGS, 2010, p. 363-364.

Na figura acima, temos, em (a), a representação do fluxo de dados durante o


processo de busca da instrução. Nota-se que, para que a instrução seja buscada
junto à memória, o registrador MAR (memory address register) deverá receber o
valor contido em PC (program counter). O valor de retorno do sistema de memória é
salvo no registrador MBR (memory buffer register), que, no caso, contém a palavra
referente à instrução. A finalização do fluxo ocorre no momento em que o valor de
38

MBR é passado ao registrador IR (instruction register) – mesmo instante em que


ocorre o incremento do PC para que, no próximo ciclo, seja buscada, a princípio, a
instrução subsequente.
Ainda em relação à figura acima, o item (b) ilustra o fluxo de dados no momento da
etapa de busca de operandos por ocasião do endereçamento indireto de memória.
O valor buscado no sistema de memória (alocado em MBR) representa, na
verdade, o endereço no qual se deseja o valor a ser manipulado. Diante disso, um
novo ciclo é necessário para providenciar essa busca, sendo, então, para isso,
necessária a transferência do valor inserido no MBR para o MAR.
Por fim, temos, em (c), o fluxo de dados inerente ao tratamento de uma interrupção.
A transferência do valor de PC para o MBR relaciona-se com o salvamento de
contexto, para que o ponto de processamento seja restaurado após a finalização da
execução do código da interrupção. Sendo assim, o valor de PC será salvo em um
segmento de pilha na memória, cujo ponteiro é passado pela unidade de controle
ao MAR.

Quando se fala sobre fluxo de dados, correlacionando-o com o fluxo de instruções, vem à mente a
Taxonomia de Flynn. Essa classificação abrange quatro tipos de modelos computacionais: SISD (Single
Instruction, Single Data), SIMD (Single Instruction Multiple Data), MISD (Multiple Instruction, Single Data) e
MIMD (Multiple Instruction, Multiple Data). Saiba mais no artigo (CARVALHO, 2017):
<https://pt.linkedin.com/pulse/o-processamento-paralelo-e-taxonomia-de-flynn-carlos-eduardo>.

Mas, cabe a questão, qual a relação do fluxo de dados com o pipeline? A resposta
reside no fato de que alterações no tempo de execução (havendo ou não a
necessidade de ciclos extras de clock para a finalização de uma etapa) e de que
alterações no chaveamento de comunicação entre os módulos alterará o modo de
processamento e, consequentemente, impactará sobre o pipeline.

Um dos principais algoritmos para a manipulação da execução de instruções envolvendo pipeline é o


algoritmo de Tomasulo, criado por Robert Tomasulo (projetista da empresa americana IBM – International
Business Machines), em 1967. O algoritmo serve de base para várias implementações utilizadas nos
computadores atuais (FERREIRA, 2005). Para saber mais leia o artigo:
<http://www.ic.unicamp.br/~rodolfo/Cursos/mo401/2s2005/Trabalho/049239-tomasulo.pdf>.

No modelo de sistema computacional superescalar, as instruções poderão ser


despachadas fora de ordem caso haja disponibilidade de hardware e de dados para
a sua execução. Porém, nesse caso, além do fluxo de dados, o pipeline também
precisará se preocupar com outros detalhes que afetarão o seu desempenho
computacional. Tais detalhes são chamados como conflitos ou riscos (hazards). Os
hazards podem ser classificados como estruturais, de dados ou de controle
(PATTERSON, 2014).
39

No vídeo do professor Ricardo Santos (2015), da UFMS (Universidade Federal de Mato Grosso do Sul),
você pode saber mais sobre o pipeline e seus hazards, acesse a aula disponível em
<https://www.youtube.com/watch?v=9DOVl4aNYa0>.

Nos hazards estruturais, o pipeline é penalizado pela inexistência de recursos de


hardware para que possa executar uma instrução. Como exemplo de hazard
estrutural podemos citar o caso do pipeline que tenta buscar um certo operando,
porém não é possível pois o sistema de memória está atendendo a gravação de
resultado de uma instrução anterior.
Já os hazards de dados podem ser classificados em três categorias (PATTERSON,
2014):

• leitura após escrita: no exemplo, (i) R3 = R1 + R2; (ii) R2 = R4 + R5, temos


um hazard do tipo leitura após escrita, pois, caso a linha (ii) seja finalizada
antes da carga de R2 na linha (i), teremos a manipulação de um valor
errôneo na produção de R3;
• escrita após leitura: ocorre quando a produção da informação pela
instrução i ocorre após a ocorrência da leitura pela instrução j (sendo i < j);
• escrita após escrita: quando a instrução k modifica o valor do resultado da
instrução i, porém existe uma instrução intermediária j que deveria ler o
valor produzido por i (com i ocorrendo antes do j, que ocorre antes de k).

Para melhor gerenciar os hazards estruturais e de dados, pode-se adotar uma


solução baseada em Scoreboard ou Algoritmo de Tomasulo e suas variações, e
renomeamento de registradores (PATTERSON, 2014). Enfim, são inúmeros os
projetos e estudos para que seja permissível a adoção de máquinas cada vez mais
eficientes.
Por fim, os hazards de controle relacionam-se às instruções de desvio. Para evitar a
paralização do pipeline enquanto a expressão lógica do desvio estiver em
processamento, o processador tentará prever qual alternativa tomar. Para tanto,
pode-se utilizar uma tabela ordenada pelos LSBs (less signitificant bit – bits menos
significativos) contendo a resultado da expressão lógica da iteração anterior. Com
esse valor, o processador antecipará a execução da próxima linha de instrução,
efetivando o resultado apenas após a confirmação do caminho certo que deveria
ser tomado (caso tenha tomado o caminho errado, descarta-se o resultado).
Assim como os hazards estruturais e de dados, existem, também, mecanismos para
atenuar o impacto dos hazards de controle, dentre os quais podemos mencionar a
previsão dinâmica de desvios.

2.4. Aritmética do computador

Tudo o que é armazenado e manipulado no computador consiste em informações


numéricas. Mais especificamente, esses números seguem um modelo de
representação binária. Como você deve estar acostumado em programação,
40

existem os tipos de dados (por exemplo, em C/C++: char, int, float etc.) que
possuem uma faixa de valores derivada de seu tamanho (em bits). Por exemplo,
caso estejamos manipulando uma variável do tipo char, significa que poderemos
representar valores de -128 a 127, ou seja, metade de sua capacidade de
representação consistirá de valores positivos e metade de valores negativos. Mas
por que esse valor? Nesse caso, quando se manipula tipos cuja largura é de 8 bits,
tem-se 256 valores possíveis (28 = 256). No entanto, cabe o questionamento, como
representar um valor em binário?

Apesar do conceito de lógica binária nos acompanhar desde os primórdios dos tempos (somos seres
dicotômicos), apenas no século XIX é que o pensamento binário foi formalizado através da Álgebra
Booleana. O idealizador dela foi o matemático e filósofo britânico George Boole. Leia mais no artigo
(PIROPO, 2012): <http://www.techtudo.com.br/artigos/noticia/2012/08/uma-algebra-diferente.html>.

Todo valor, em qualquer base numérica, poderá ser fatorado. Por exemplo, o valor
876(10) poderá ser fatorado como:
876(10) = 800 + 70 + 6
= 8*102 + 7*101 + 6*100.

No caso acima, o elemento que está sendo exponenciado, corresponde à própria


base. Sendo assim, a fatoração de valores binários não é diferente, ou seja, o
processo é o mesmo em relação à base decimal, porém, ao invés de trabalharmos
com a base 10, trabalharemos com a base 2. Por exemplo, o valor:

1011(2) = 1*23 + 0*22+1*21 + 1*20


= 8 + 0 + 2 + 1 = 11(10).

O processo apresentado acima corresponde à conversão de um valor na base


binária para a base decimal.

Você pode notar que ao ser realizada a exponenciação da base pelo expoente que
representa o grau de significância do termo, em função de sua localização,
obtémse: [23; 22; 21;20 = 8; 4; 2; 1] (WEBER, 2012). Dessa combinação, originou-se
o nome do modelo de representação binária que utilizamos: BCD 8421 (binary
coded decimal).
Ainda assim como chegamos nos fatores que deverão ser multiplicados à base
exponenciada? Simplesmente fazendo divisões sucessivas pela base e coletando
os restos obtidos. As divisões pela base serão realizadas enquanto pudermos
dividir pela base. Na última divisão, coleta-se o quociente. Esse processo de
divisões sucessivas representa a forma de como convertemos um valor decimal em
binário (realizando divisões sucessivas por 2).
Mas, voltando à programação em C/C++, o que acontece quando utilizamos o
modificador de tipo unsigned? Esse modificador faz com que a variável represente
apenas valores positivos. No caso do unsigned char, todos os 256 valores possíveis
41

serão positivos (0 a 255). Isso ocorre porque, na verdade, na representação que


permite trabalharmos com valores negativos, gasta-se 1 bit para representar o
sinal. O bit mais significativo (MSB – most significant bit) representa o sinal. Caso o
MSB seja zero, então o valor representado é positivo, caso contrário, um valor
negativo é representado. Diante desse fato, tem-se 2 7 valores negativos (-128 a -1)
e 27 valores positivos (0 a 127).
Essa ideia da possibilidade de se operar valores negativos e positivos remete a
uma forma de representação denominada como complemento 2. Para se converter
um valor de positivo para negativo ou negativo para positivo, usa-se o mesmo
algoritmo constituído por duas fases: a) inverte-se todos os bits da palavra; b)
soma-se o valor um ao valor com os bits invertidos.
Sobre os valores binários representados em BCD 8421 ou em complemento dois,
poderão ser realizadas operações aritméticas de forma análoga ao processo
empregado em valores com representação decimal.
Além dos valores inteiros, existe também a representação dos números reais,
conhecidos, computacionalmente, por ponto flutuante (float, em C/C++). O
complemento dois é padronizado pelo IEEE sob número 754, que permite
armazenar um valor de maneira semelhante à notação científica.
Na nossa notação científica, temos, por exemplo, o número 532,41 representado na
forma 5.3241E2, ou seja, 5.3241 * 10 2. Nesse exemplo, temos, como mantissa o
valor 5.3241 e, como expoente, o valor dois.
A responsabilidade de execução das instruções aritméticas, assim como as de
operações lógicas, são de responsabilidade da Unidade Lógica e Aritmética.

2.4.1 Unidade Lógica e Aritmética (ULA)

A unidade lógica aritmética (ULA ou ALU – Arithmetic-Logic Unit) é o módulo de


hardware integrante do computador, cuja função é realizar operações aritméticas e
lógicas.
De forma simplista, podemos falar que a ULA realiza interfaceamento com o banco
de registradores, de modo que ela possa coletar os valores a serem manipulados
pelas operações aritméticas (como soma, multiplicação sobre números inteiros ou
ponto flutuante) e pelas operações lógicas (como operação AND, deslocamentos
etc.).

Você sabia que, em C/C++, você poderá fazer operações bit-a-bit? Por exemplo, faça
um programa e teste a diferença no resultado entre as atribuições usando operações
lógicas (exemplo: C = A && B; D = E || F) e operações bit-a-bit (exemplo: C = A & B; D
= E | F). Você sabia, também, que poderá realizar divisões, por exemplo, por dois
usando operação lógica? Experimente substituir: A = A / 2 pelo comando: A = A >> 1.
O operador lógico >> denota deslocamento, no caso, deslocamento para a direita
uma vez.
42

Como resultados, a ULA fornece o valor da operação propriamente dito e, também,


é responsável por gerar os bits do registrador de flags (indicando, por exemplo,
resultado negativo, nulo e overflow).
Para uma melhor compreensão da manipulação aritmética, você pode consultar o
capítulo 9 de (STALLINGS, 2010).

2.4.2 Unidade de Controle (UC)


A unidade de controle do processador tem por objetivo gerenciar todo o fluxo de
execução das instruções. Esse gerenciamento é conseguido pelo envio de sinais
de controle aos módulos da CPU, ativando-os quando necessário e pelo
roteamento das informações de forma a encaminhá-las de forma apropriada.
A ULA poderá executar instruções da forma reg op reg (quando os dois operandos
estão armazenados em registradores) ou reg op constante (a instrução representa
uma operação entre o valor do registrador e uma constante). Você pode já imaginar
que a UC, além de ativar a ULA, também deverá selecionar os operandos que
incidirão no processamento. A figura abaixo, extraída de (PATTERSON, 1998),
ilustra o interfaceamento entre a UC e a ULA.
43

Deslize sobre a imagem para Zoom

Figura 7 - Datapath do processador MIPS destacando-se a interface entre unidade de controle e a ALU e o
chaveamento no fluxo de dados a ser encaminhado à ALU. Fonte: Adaptada de PATTERSON, 1998, p. 209.

Na figura acima, nota-se que o módulo de controle, responsável pela decodificação


das instruções, produz, para a ALU, dois sinais de controle: ALUop (operação de
ALU) e ALUsrc (ALU source – ALU fonte). A seleção do dado é realizada por
intermédio de um seletor denominado como MUX (também conhecido como
multiplexador ou multiplex). O outro operando é coletado, sempre, do banco de
registradores. O sinal “Read data 1” representa o conteúdo do registrador apontado
por Read Register 1.
Por fim, tem-se, com saídas da ULA, o valor propriamente dito e, também, sinais do
registrador de flags para indicar o status de seu processamento – no caso da figura,
o bit zero. Ainda em relação à figura anterior, temos, para facilitar o processo de
decodificação e demais ações, a quebra da palavra de instrução em vários
pedaços. Por exemplo, o opcode das instruções corresponde aos bits 31 ao 26.
Você poderá notar, ainda na figura acima, que o datapath em questão é de um
processador típico RISC. Mas como chegou-se à tal conclusão? Observando-se as
entradas da ULA, percebe-se que operações do tipo soma (ADD) manipulam três
registradores (dois fontes e um destino), as operações de ULA são da forma
reg_destino, reg_fonte_1, reg_fonte2.
Para finalizar, podemos falar que o funcionamento do computador, em sua
essência, é algo básico – baseado em decodificações, envio de sinais de controle,
44

roteamento de informações. O que o torna complexo são as técnicas cada dia mais
agressivas para conseguir, continuamente, aumentar o poderio de processamento e
de sua performance computacional. Essas técnicas são baseadas no pipeline e na
superescalaridade. Um outro complicante no quesito de complexidade é
representado pelo processamento paralelo cada vez mais atuante e presente.
Temos vários exemplos e níveis de paralelismo: nível de programação, nível de
pipeline (pseudoparalelismo), nível de superescalaridade e, por fim, nível de
múltiplos núcleos (cores – físicos e virtuais) de paralelismo.

Síntese
Você chegou ao final do capítulo que aborda conceitos inerentes à forma da representação e do
armazenamento de informações dentro do processador para que sejam executados. Novamente, foi
necessário abordar os conceitos de arquitetura e organização – conceitos que ora se mesclam e ora
são totalmente distintos.

A partir dos pontos que abordamos neste capítulo, esperamos que você se sinta confortável e
motivado a prosseguir os estudos relacionados ao funcionamento do computador e a aplicar os
conhecimentos adquiridos em seu dia a dia – seja em atividades de consultoria, na implementação
de sistemas ou, ainda, em seu cotidiano pessoal. Esperamos, também, que você, a partir das
informações até aqui apresentadas, vislumbre soluções, cada vez mais eficientes e “elegantes” para a
implementação de sistemas computacionais.

Neste capítulo, você teve a oportunidade de:


• identificar os elementos constantes da arquitetura de computadores de
modo a poder compreender as funcionalidades inerentes aos módulos
pertencentes à máquina e, depois, de forma mais focada, pertencentes
ao processador;
• compreender a forma de organização interna do processador,
identificando a organização dos registradores, e reconhecer as
funcionalidades dos registradores assim como aplicá-los no contexto
de tradução de código para linguagem de máquina;
• inferir sobre o processo de execução de instruções, identificando os
pontos de controle do sistema computacional. Compreender e aplicar
os conceitos
relacionados ao processo de tradução de uma linguagem de alto nível
para o assembly (linguagem de máquina);
• entender a aritmética computacional assim como identificar os elementos
de interfaceamento entre a ULA e a Unidade de Controle.

Projeto
COMPUTADORES E O FUTURO
45

O ser humano sempre seguiu uma linha crescente de


desenvolvimento que pode ser observada desde os primórdios.
Indivíduos que há milhares de anos se organizavam em grupos
nômades vivendo da caça e coleta, com a descoberta da agricultura
passaram a se organizar em comunidades sedentárias.

O processo evolutivo foi caracterizado por acontecimentos e fatos


marcantes, como na Grécia Antiga, pela criação e pelo
desenvolvimento da lógica abstrata pelos grandes filósofos: Sócrates,
Platão e Aristóteles. Mais tarde, no século XIX d.C., a conversão dessa
lógica em regras matemáticas foi feita por George Boole, criando a
lógica booleana, utilizada nos circuitos de todos os computadores
produzidos atualmente.

Os computadores são equipamentos compostos por diversas


componentes, sendo os principais: processador (composto pela ULA,
responsável por realizar operações lógicas e aritméticas), UC
(responsável por decodificar e executar as instruções coletadas na
memória), memória (cuja função é armazenar as informações) e
interfaces de entrada e saída (interface do computador com o mundo
externo). Essa foi a arquitetura idealizada inicialmente por John von
Neumann, quando criou o IAS (de 1946 a 1952), muito aprimorado
com o passar dos anos e atualmente utilizado nos modernos
computadores.

Atualmente, temos modernos computadores que são baseados na


arquitetura de John von Neumann, cujos circuitos operam conforme
as regras da lógica booleana.

O mundo moderno exige eficiência e, para isso, as empresas buscam


profissionais cada vez mais atualizados, com conhecimentos
multidisciplinares e equipamentos que atendam às suas
necessidades. Os computadores são projetados para atenderem às
exigências de eficiência ditadas pelo mercado.
46

Os fabricantes de processadores procuram constantemente inovar,


produzindo processadores mais poderosos, tornando, assim, os
equipamentos mais rápidos e eficientes, facilitando a vida das
pessoas e aumentando o rendimento da atividade produtiva das
empresas.

A fabricante de processadores Intel, fundada em 1968 por Robert


Noyce e Gordon Moore, é um exemplo de empresa atua no ramo de
tecnologia há décadas, produzindo componentes eletrônicos, como
memórias e processadores, contribuindo para a evolução dos
computadores.

Anualmente, são organizadas feiras tecnológicas nas quais os grandes


fabricantes apresentam suas criações para o mercado consumidor.
Esses eventos chegam a ser visitados por milhares de pessoas, entre
elas amantes da tecnologia e empresas que buscam inovar sua
atividade.

A CES 2019 - Consumer Electronic Show, a maior feira de tecnologia


do mundo, reuniu muitos fabricantes e uma infinidade de novas
tecnologias e inovações que atraíram a atenção mundial. Nessa feira,
a fabricante Intel, sendo representada pelo então vice-presidente
Gregory Bryant, anunciou os avançados processadores Spring Hill e
Spring Crest.

O processador NNP-I 1000, codinome (Spring Hill), é o primeiro chip


de inteligência artificial lançado pela Intel, sendo o resultado de US$
120 milhões de investimento em três empresas israelenses. Esse
dispositivo é baseado em um processador Ice Lake de 10
nanômetros, sendo capaz de suportar altas cargas de dados,
oferecendo às empresas uma resposta eficiente para análise dos
dados onde forem coletados.

Outro lançamento da Intel foi o processador NNP-T, codinome (Spring


47

Crest), muito mais poderoso que o Spring Hill, baseado em um chip de


16 nanômetros da TSMC, possuindo a finalidade de treinar redes
neurais, tendo em vista que estas exigem grande capacidade de
processamento. O NNP-T é altamente escalável, ou seja, vários chips
podem ser colocados para trabalhar conjuntamente com relativa
facilidade, aumentando ainda mais seu desempenho.

Segundo os representantes da empresa, o objetivo da Intel é, no


futuro, criar um ambiente de inteligência artificial em todos os
computadores, em que os dados serão analisados diretamente
quando captados, servindo posteriormente para o treinamento de
redes neurais. Isso possivelmente trará diversos benefícios, tanto para
os consumidores quanto para as empresas que se servirão de
equipamentos muito mais eficientes, tornando-as mais competitivas
no mercado.

Ambas as tecnologias foram apresentadas ao mercado consumidor,


sendo que amostras já foram enviadas a empresas, como o Baidu e
Facebook, e a produção desses processadores deve ter início no fim
de 2019.

Conforme observamos, o mercado consumidor está cada vez mais


exigente, fazendo com que os fabricantes inovem constantemente.

Mas o que esperar para o futuro? Para o futuro, podemos esperar o


aumento em larga escala da capacidade computacional e o
barateamento de tais tecnologias, viabilizando sua aquisição e
utilização.

Um novo modelo tecnológico deve se desenvolver nos próximos anos,


direcionando o mercado para a fabricação de equipamentos
equipados com inteligência artificial, capazes de analisar os dados e
apreender posteriormente.

Logicamente, estamos falando em supercomputação que,


futuramente, tornar-se-á algo rotineiro, retirando os limites para os
48

avanços tecnológicos, ampliando os horizontes para diversos


segmentos de pesquisas, quando possivelmente teremos muitas
descobertas espetaculares que mostrarão ao ser humano sua
grandiosidade.

Vamos praticar

Faça um texto crítico, em uma lauda, que retrate como os computadores funcionam, sua
composição, as novas tecnologias de processadores da fabricante Intel, como os processadores
Spring Hill e Spring Crest da Intel, apresentados por Gregory Bryant, vice- presidente da
empresa na CES 2019, e o que podemos esperar para o futuro.

No seu texto, você deverá discorrer sobre a questão da supercomputação e a nova geração de
processadores apresentadas pelas gigantes do ramo.

ARQUITETURA E ORGANIZAÇÃO DE
COMPUTADORES
U 3 - EM QUE CONSISTE O PROCESSAMENTO DAS
INSTRUÇÕES E COMO O PROJETO DA MEMÓRIA
PODE AUXILIAR?

Fernando Cortez Sica

Introdução

Você chegou até aqui vendo muito conteúdo interessante sobre o funcionamento e a
concepção básica dos computadores. Que tal falarmos agora sobre o processamento das
instruções e alguns itens relacionados à memória?

Neste capítulo, vamos estudar essas questões. Começaremos com a unidade de controle, para
que possamos ter a resposta para o possível questionamento: como o processador
efetivamente processa as instruções? Neste ponto, abordaremos o que vêm a ser as
microoperações e como elas são abstraídas e tratadas pelo processador.
49

A essa altura, poderá estar se formando, em sua mente, mais uma pergunta: se existem as
micro-operações, o tratamento de interrupções também é abstraído como uma sequência de
instruções divididas, ainda, em micro-operações? Assim, para encontrar as respostas,
abordaremos a questão das interrupções apresentando um fluxo de execução realizado pelo
processador.

Também vamos estudar alguns conceitos relacionados à interconexão. Assim, o processador


conseguirá buscar, nos demais módulos pertencentes ao computador, as informações e
instruções que deverão ser manipuladas.

Por fim, serão abordados aspectos do sistema de memória. O sistema de memória é alvo de
muitas pesquisas pelo fato de ser um grande gargalo que impacta a performance
computacional. Então, poderá surgir mais uma questão: como atuar no projeto do sistema de
memória para que se possa melhorar o seu desempenho? A resposta está nos quesitos ligados
à hierarquia de memória e à memória cache.

A partir dos pontos abordados neste capítulo, você terá condições de responder às indagações
inerentes à performance computacional e, também, favorecer o desenvolvimento de sistemas
computacionais ainda mais eficientes.

Vamos em frente? Bons estudos!

3.1 Unidade de Controle (UC)

A UC tem como principal objetivo gerenciar todas as etapas de processamento de


uma instrução sincronizando os submódulos internos do processador por
intermédio da geração de sinais de controle. No entanto, cabe a pergunta: como a
UC consegue fazer isso?
A resposta inicia na fase da implementação da UC, concebida pela metodologia
conhecida como implementação por hardware (hardwired). Nesta técnica, as etapas
de processamento de uma instrução são mapeadas pelos circuitos de eletrônica
digital, em que um conjunto de portas lógicas consegue decodificar a instrução em
questão, gerando os sinais de controle.
A partir deste ponto, você pode ter, em sua mente, outra pergunta: quais etapas de
instrução são essas? Uma instrução, para que se possa aproveitar melhor os
recursos computacionais e, também, para que os submódulos sejam mais simples,
rápidos e otimizados, é quebrada em várias micro instruções (ou micro-operações).
A execução de cada micro-operação ficará sob a responsabilidade de um módulo
de hardware específico.

Os processadores da Intel, como é o caso do Core i7, são tidos como processadores híbridos, pois
mantêm, em sua arquitetura e de forma fortemente acoplada, núcleos baseados no padrão CISC
(Complex Instruction Set Computer) e no padrão RISC (Reduced Instruction Set Computer) (RAISCH, 2010).
Leia mais sobre os processadores:
<https://www.ibm.com/developerworks/community/blogs/tlcbr/entry/computadores_hibridos_a_proxima_fr
onteira_da_computacao?lang=en>.
50

Essa divisão da instrução em etapas menores favorece o pipeline, por meio do qual
consegue-se antecipar, mais facilmente, o início de uma nova instrução.

3.1.1 Micro-operações

Sabemos que cada instrução é dividida em várias operações mais simples


denominadas como micro-operações. Mas, não somente a fase de execução
propriamente dita é dividida em micro-operações, também, todas as etapas de
execução da instrução, ou seja, todo o ciclo de instrução.

Deslize sobre a imagem para Zoom

Figura 1 - Divisã o das etapas de execuçã o em micro-operaçõ es, sendo que cada micro-operaçã o é executada em
um pulso de má quina. Fonte: STALLINGS, 2010, p. 462.

Na figura acima podem ser notadas as micro-operações em todo o ciclo de


instrução. A etapa de busca da instrução poderá ser, então, dividida em micro-
operações, tais como:

• instanciaçã o do registrador MAR (Memory Address Register), com o valor contido


em PC (Program Counter);
• ativaçã o do sistema de memó ria, para acessar o endereço cuja localizaçã o está
constando no MAR. O valor retornado pela memó ria será salvo no registrador
MBR (Memory Buffer Register);
• incrementaçã o do valor do registrador PC. Essa micro-operaçã o poderá ser
realizada concomitantemente à micro-operaçã o descrita anteriormente;
51

• có pia do valor buscado da memó ria, que foi salvo no registrador MBR para o
registrador IR (Instruction Register).

Ainda em relação à figura acima, o mesmo processo de divisão de uma fase dentro
do ciclo de instrução pode ser aplicado ao ciclo indireto. O ciclo indireto ocorre na
fase de busca dos operandos. Nessa ocasião, o ciclo pode ser dividido nas
microoperações abaixo listadas:

• registrador MAR recebe o campo do IR, que contém o endereço de memó ria, o
qual contém a referência para que seja acessada a informaçã o requerida;
• acessa-se a memó ria na posiçã o MAR para coletar a referência de memó ria e
armazená -la no MBR;
• atualiza-se o campo de IR para que se possa, na pró xima fase, acessar a
localizaçã o definitiva de memó ria que contém a informaçã o a ser manipulada.

O cientista da computação Maurice Vincent Wilkes (1913-2010), foi o responsável pelo projeto do
computador EDSAC, em 1949, quando a ideia de micro-operações foi concebida. Mais tarde, essa ideia
foi utilizada pela empresa americana IBM em sua série 360, no ano de 1964 (UFRGS, 2010). Em 1967,
Wilkes recebeu o Prêmio Turing, por essa e outras contribuições. Para conhecer mais sobre a trajetória
de Wilkes acesse: <http://www.ufrgs.br/mvs/Periodo02-1949-ElectronicDelay.html>.

Como mencionado, essa divisão em micro-operações em muito facilita a técnica de


pipeline, sendo que o tempo para a execução de uma micro-operação é muito
menor em relação ao tempo para processar toda a instrução. Por consequência, os
módulos responsáveis pela execução da micro-operação tornam-se disponíveis
mais rapidamente, favorecendo, portanto, o início de execução da micro-operação
referente à instrução seguinte.

3.1.2 Ciclos de interrupção, execução e instrução

A interação entre os dispositivos de E/S (entrada e saída ou I/O – input/output) é


feita mediante o envio de sinais de interrupção. Uma interrupção é tratada de
acordo com uma sequência de instruções análoga à de um processo (programa em
execução). Sendo assim, o processo sob processamento deverá ser interrompido
para que sejam carregadas, no pipeline, as instruções relativas à interrupção. No
entanto, se uma interrupção, em nível do ciclo de instruções, comporta-se como um
processo, então ela também é quebrada em micro-operações? A resposta é sim.
Não somente o código, relativo à interrupção em si, é dividido em micro-operações,
mas, também, a troca de contexto. Salvar contexto denota a operação de
armazenar, na memória (estrutura em pilha), informações tais como o valor do
registrador PC, para que, ao término da interrupção, seja possível retornar
exatamente ao ponto de parada do programa. As micro-operações para o
atendimento da interrupção podem ser expressas na sequência de micro-
operações descritas a seguir:

• registrador MBR recebe o valor do PC para que seja empilhado;


52

• registrador MAR é instanciado com a localizaçã o do topo do segmento de pilha


(stack segment);
• PC é setado com o endereço da rotina de tratamento da interrupçã o; • a
memó ria é acessada para efetivar o empilhamento do PC (contido no MBR).

Na implementação do tratamento de interrupção, o seu término é marcado por uma


instrução do tipo IRET (Interrupt Return). As micro-operações relativas ao IRET são
parecidas à sequência acima, porém ocorre o desempilhamento do registrador PC.
Até o momento, foram referenciadas etapas fixas. Mas você deve estar se
perguntando: tudo é assim tão fixo e previsível? As micro-operações para a fase de
execução são também fixas como nas etapas de busca da instrução, ciclo indireto e
tratamento da interrupção independentemente do tipo e funcionalidade da
instrução? Cada instrução pertence a um grupo distinto e apresenta uma
funcionalidade também distinta. Então, é de se esperar que a sequência de micro-
operações varie de instrução para instrução – mesmo entre instruções da mesma
classe (mesmo formato de instrução).

Você sabia que o processador Intel Core i7, Nehalem, possui um conjunto de
instruções composto por macro-instruções CISC (Complex Instruction Set Computer)
que são traduzidas em micro-operações RISC (Reduced Instruction Set Computer)? E
que, para executar as micro-operações, o i7 apresenta um pipeline com profundidade
de 14 estágios? Detalhes dessas afirmativas você poderá encontrar em Hennessy
(2014).
Tomemos, para ilustrar a divisão da etapa de execução em micro-operações, duas
instruções hipotéticas quaisquer: a primeira trata de uma escrita na memória do tipo
STORE posição, e, a segunda, um desvio condicional do tipo JZ offset (jump caso
zero).
Para a instrução do tipo STORE posição, vamos supor que o valor a ser salvo na
memória, encontra-se no registrador acumulador. Nesse caso, a instrução poderá
ser decomposta nas seguintes micro-operações:

• salvar o valor do acumulador no registrador MBR;


• carregar, no registrador MAR, o campo de endereço presente no registrador
IR; • acessar a memó ria para efetivar a gravaçã o.

Já com relação à instrução JZ offset, vamos supor que a operação de comparação


(ou subtração), que servirá de base à instrução de desvio condicional já tenha
ocorrido. Dessa forma, a instrução JZ offset poderá ser decomposta nas seguintes
micro-operações:

• carregar, em algum registrador R, o valor contido no IR (offset);


• somar, ao registrador R, o valor de PC; • caso flag Z seja igual a zero,
entã o PC recebe o valor de R.

Apesar de, em ambos os exemplos, as instruções terem sido divididas,


coincidentemente, em quatro micro-operações, na realidade, o número de
microoperações pode se diferenciar nas diferentes instruções.
53

Convém lembrar que o número de micro-operações está relacionado à


implementação do processador (organização). Sendo assim, processadores da
mesma família (apresentando a mesma arquitetura) podem variar em relação ao
número e à forma das micro-operações.
Para controlar a sequência de operações das micro-operações, a unidade de
controle manipula um registrador especial para tal função: o ICC (instruction cycle
code). Esse registrador é instanciado ao longo da execução das micro-operações
para armazenar o estado corrente e, consequentemente, determinar a próxima
micro-operação a ser realizada. A figura a seguir ilustra um fluxograma da execução
das micro-operações a partir do valor instanciado no registrador ICC.

Deslize sobre a imagem para Zoom

Figura 2 - Fluxograma da execuçã o das micro-operaçõ es a partir do valor instanciado no registrador ICC.
Fonte: STALLINGS, 2010, p. 467.

Na figura acima, as ações são representadas pelos retângulos, e os hexágonos


representam as tomadas de decisão em função do valor do registrador ICC. Na
figura, foram convencionados os seguintes valores para ICC: 00 = busca; 01 =
indireto; 10 = execução; 11 = interrupção. Dessa forma, foram representadas todas
as etapas inerentes ao ciclo de instrução. Com base no valor do ICC, o hardware
pode acionar os submódulos correspondentes e rotear as informações por entre
eles.

3.2 Funçã o do computador e interconexã o


54

Você já deve estar familiarizado com o fato de que o computador tem por finalidade
executar instruções pertencentes a um programa (programas do usuário, do próprio
sistema operacional ou referentes ao tratamento das interrupções). Todas as
instruções estão dentro de uma das seguintes classes: processador-memória,
processador-E/S, processamento propriamente dito e controle.
Então, as micro-operações devem, também, abranger as funcionalidades básicas
do computador. Segundo Stallings (2010), as funcionalidades das micro-operações
estão classificadas da seguinte forma:

• movimentaçõ es de dados do tipo registrador-registrador;


• movimentaçõ es de dados entre registrador e barramento (para interfacear,
por exemplo, o sistema de memó ria); • efetuar operaçõ es ló gicas ou
aritméticas.

Como você pode ter notado, essas funcionalidades das micro-operações são
evocadas para o tratamento das interrupções e, por diversas vezes, acessam os
barramentos do sistema para completar as suas ações. Diante desse fato, vamos,
agora, dar um foco nas interrupções e nos barramentos do sistema computacional.

3.2.1 Interrupções: sequenciais, múltiplas e aninhadas

Interrupções são eventos utilizados para interfacear os dispositivos de E/S com o


processador. Elas podem ocorrer a partir da evocação do dispositivo (por exemplo,
quando é pressionada uma tecla do teclado) ou a evocação pode partir do software
(por exemplo, o programa necessita salvar uma informação em um arquivo).
Em ambos os casos, elas deverão ser tratadas, interrompendo o fluxo de
processamento dos aplicativos abertos. A figura abaixo ilustra o tratamento das
etapas de execução de uma instrução envolvendo a manipulação de interrupções.

Deslize sobre a imagem para Zoom


55

Figura 3 - Sequência de etapas para execuçã o das instruçõ es, sendo que, apó s cada instruçã o, há a verificaçã o da
existência de solicitaçõ es de interrupçõ es. Fonte: STALLINGS, 2010, p. 363.

Na figura acima, nota-se que, após a execução de uma instrução ser completada,
há a verificação, se há alguma interrupção enfileirada pendente a ser executada.
Nesse caso, ela entraria como um processo normal, ou seja, as instruções
vinculadas ao tratamento da interrupção entrariam no fluxo do pipeline.
Quando um fluxo de execução é adicionado ao pipeline, o que acontece quando
alguma outra interrupção ocorre? Quando esse cenário ocorre, temos duas
maneiras de realizar o tratamento: na primeira forma, assim que o tratamento da
interrupção for iniciado, poderemos desabilitar novas interrupções ou permitir que
as próprias interrupções sejam interrompidas para o atendimento de outras. A figura
abaixo mostra a diferença entre esses dois enfoques.

Deslize sobre a imagem para Zoom

Figura 4 - Tratamento de interrupçõ es com a desabilitaçã o de novas interrupçõ es (a) e tratamento de novas
interrupçõ es de forma aninhada (b). Fonte: STALLINGS, 2010, p. 65.
56

Em relação à figura acima, temos o tratamento de interrupções sequencialmente


(a). Nesse tipo de enfoque, ocorre a desabilitação de interrupções, para que as
novas que ocorrerem sejam apenas enfileiradas, de modo que o tratamento ocorra
somente após o término da atual. Por sua vez, no tratamento aninhado (b), uma
interrupção poderá ser descontinuada, para que seja tratada uma com maior
prioridade. Em ambos os casos (sequencial ou aninhado), ocorrerá a interrupção da
execução dos processos do usuário para que as interrupções sejam tratadas pelo
pipeline.

3.2.2 Barramentos: de endereço, dados e controle

Mais uma vez retomando as classes das instruções, você pode notar que existem
instruções que dependem de uma estrutura de comunicação com os demais
módulos do computador (memória e dispositivos de E/S), para que possam ser
processadas.
Essa estrutura de comunicação é provida pelos barramentos. A figura a seguir,
ilustra, em linhas gerais, as interfaces requeridas pelos módulos do computador e a
estrutura básica de uma rede de interconexão (barramento).
57

Deslize sobre a imagem para Zoom

Figura 5 - Interfaces requeridas pelos mó dulos do computador (a) e a estrutura bá sica de um barramento
(b). Fonte: Adaptada de STALLINGS, 2010, p. 67-69.

Como você pode notar na figura acima, as interfaces dos módulos do computador,
em (a), correspondem, em suma, às linhas de dados, endereços e de sinais de
controle. Sendo assim, um barramento deve ter, em sua funcionalidade básica, vias
para o tráfego de tais sinais (exibidos em (b), destacados em vermelho):

• vias de dados: as vias de dados sã o responsáveis pelo trá fego, em paralelo, das
informaçõ es a serem processadas, armazenadas ou enviadas aos dispositivos de
E/S;
• vias de endereçamento: tem por objetivo transmitir endereços de memó ria ou
de mó dulos de E/S;
• vias de sinais de controle: como sinais de controle podemos ter (STALLINGS,
2010):
- leitura/escrita de memória: define a operação a ser realizada quando o acesso à
memória for solicitado;
- leitura/escrita de E/S: define a operação a ser realizada quando o acesso a
algum dispositivo de E/S for solicitado;
- ACK de transferência (acknowledgment): o ACK é um sinal de reconhecimento
cuja função é avisar o término, de forma satisfatória, da operação de transferência;
58

- solicitação de barramento: sinal gerado por algum módulo para que use o
barramento;
- concessão de barramento: resposta à solicitação de barramento, outorgando ao
módulo, o direito do uso do barramento;
- requisição de interrupção: sinal que indica a pendência de alguma interrupção;
- ACK de interrupção: reconhecimento da interrupção que estava pendente;
- clock: pulsos de sincronização;
- reset: efetua a reinicialização dos módulos.

Em alguns modelos de barramentos, como o PCI (Peripheral Component


Interconnect), as vias de endereçamento e de dados são multiplexadas. Em canais
multiplexados, as vias podem atender às funcionalidades de transporte de forma
alternada, ou seja, em certos momentos, transmite-se endereços e, em outros, os
dados são trafegados.

Barramentos não são específicos para realizar a interconexão apenas de módulos


internos do computador. Barramentos também são encontrados em sistemas
embarcados como o I2C e o wishbone. Também são encontrados em máquinas do tipo
HPC (High Performance Computer). A especialista em Teleinformática e Redes de
Computadores, Kopp (2012), aborda a construção de um HPC:
<http://repositorio.roca.utfpr.edu.br/jspui/bitstream/1/802/1/CT_TELEINFO_XX_2012_
04.pdf>.

Antes de prosseguirmos abordando barramentos, convém mencionarmos algumas


métricas e conceitos associados a eles:

• largura do barramento: referencia-se à quantidade de vias paralelas para o


trá fego de informaçõ es. A largura do barramento está associada ao tamanho da
palavra usada pelo sistema computacional em questã o – por exemplo, uma
largura de 64 bits ou de 32 bits;
• topologia: a topologia está associada ao arranjo físico para a ligaçã o dos
mó dulos. Como topologias mais comuns, encontramos: barramento, anel e linha
ponto a ponto;
• frequência de trabalho: relativo à frequência, em Hertz (Hz), do sinal de clock
usado para a sincronizaçã o dos mó dulos;
• vazão, largura de banda ou throughput: a largura de banda é o índice que
indica a quantidade de bits transferidos dentro do intervalo de um segundo (bps);
• sistema de coordenação: indica como é realizada a coordenaçã o pelo uso do
barramento. O sistema pode ser centralizado onde há um á rbitro de barramento,
cuja funçã o é receber as requisiçõ es e, usando um critério de tempo e/ou
prioridade, fornecer, a um mó dulo requisitante, a permissã o de uso do
barramento. Um mecanismo bastante usado para solicitar e obter acesso ao
barramento é denominado “handshake”. Por sua vez, denomina-se controle
distribuído quando nã o há um coordenador. Nesse caso, os pró prios mó dulos
decidem entre si qual será o detentor de uso do barramento. Para tanto, usa-se a
troca de mensagens ou a passagem de “tokens”. Em sistemas ponto a ponto,
podemos, ainda, encontrar solicitaçõ es baseadas em “daisy-chain”.
59

Um computador pode ser dotado de barramentos de vários níveis, atendendo a um


conjunto de módulos ou dispositivos. A utilização de uma hierarquia de barramentos
permite uma utilização mais eficiente evitando-se que um tipo de fluxo não impacte
negativamente em algum outro. Como exemplo, podemos ver a topologia das
máquinas usuais atuais, na figura a seguir, em dois níveis de abstração: a
configuração de uma máquina dita como convencional (a); e uma configuração de
alto desempenho (b).

Deslize sobre a imagem para Zoom

Figura 6 - Configuraçõ es de um barramento: em (a), tem-se uma configuraçã o bá sica e, em (b), uma configuraçã o
de alto desempenho. Fonte: STALLINGS, 2010, p. 71.

Na figura acima, temos uma dissociação dos barramentos em função do tipo de


comunicação requerida. Nota-se que o barramento do sistema tem por objetivo
interligar apenas o processador ao sistema de memória (memória principal e
memória cache) devido à alta demanda de uso. Os demais módulos estão sendo
interligados por barramento de alta velocidade ou barramento de expansão. No
caso, nota-se, na porção denotada por (b), que houve uma incorporação de um
barramento de alto desempenho, atendendo os dispositivos mais críticos (como a
60

placa de vídeo). Nesse caso, o tráfego do barramento de expansão fica dissociado


em relação ao tráfego do barramento de alta velocidade.
Na prática, você poderá encontrar essa hierarquia de barramentos nos chipsets
(conjunto de circuitos integrados controladores do barramento) atuais. Em tais
chipsets podemos encontrar a “ponte norte” (northbridge) como elementos de
interligação do processador com o sistema de memória e a placa de vídeo (por
exemplo, AGP ou PCI Express). Por sua vez, os demais módulos (placa de vídeo
onboard, controladoras de disco, etc.) são interligados pela “ponte sul” (southbridge).

Quer saber mais sobre chipsets e barramentos? Recomendamos o artigo de Torres (2012), no endereço:
<https://www.clubedohardware.com.br/artigos/placas-mae/tudo-o-que-voc%C3%AA-precisa-saber-
sobrechipsets-r34158/?nbcpage=1>.

Já que existe uma grande preocupação no transporte de informações entre o


processador e a memória, dedicando, para isso, um barramento (ponte norte),
então a memória também deve ser eficiente para que o tempo de resposta diante
das requisições do processador seja mínimo. Veremos, a seguir, os aspectos
inerentes à memória para que se possa garantir a eficiência no armazenamento e
na recuperação das informações solicitadas pelo processador.

3.3 Visã o geral do sistema de memó ria

Até o momento, você viu, neste capítulo, aspectos relacionados com o


processamento em si e sobre o transporte das informações (dados, instruções e
sinais de controle) pelos barramentos. Mas, como se realiza o armazenamento e
recuperação das informações? Veremos esses pontos nesta seção.

3.3.1 Características dos Sistemas de Memória

Inicialmente, pode-se falar que as características da memória variam em função da


sua funcionalidade e de sua localização. Porém algumas métricas e conceitos
podem ser aplicados em qualquer que seja o nível de memória dentro de sua
hierarquia. Com isso, segundo (STALLINGS, 2010), uma memória em específico
pode ser classificada de acordo com a sua unidade de transferência, método de
acesso, desempenho e tecnologia de fabricação.
Define-se unidade de transferência como sendo a forma com que a informação é
tratada. A informação pode ser tratada como sendo uma palavra de bits ou um
bloco (contendo várias palavras). A palavra geralmente relaciona-se com a largura
do barramento (por exemplo, 64 bits) para que as informações não precisem passar
por um processo de serialização ou paralelização, ou, ainda, não sejam
necessários vários pulsos (ciclos) de clock para ler ou gravar informações frente à
61

memória. Alguns níveis de memória, por exemplo, a memória externa (discos


rígidos), manipulam blocos de informações. Nesse tipo de memória, consegue-se
gravar ou ler todo o bloco, gastando-se apenas um ciclo de memória. Essa
quantidade de bits que poderão ser gravados ou recuperados de uma só vez se
denomina unidade de transferência.
Além da unidade de transferência, um outro aspecto a ser considerado relaciona-se
com as unidades endereçáveis. A quantidade de unidades endereçáveis é
proporcional à quantidade de bits que compõem o endereço. Por exemplo, em um
sistema cujo tamanho da palavra é de 16 bits, teremos 216 linhas de endereçamento
de memória (unidades endereçáveis). Caso a largura da memória seja também de
16 bits então, teremos: 216 = 65.536 (64 k) unidades endereçáveis. Cada unidade
compreende 16 bits (2 bytes), então a capacidade total da memória é de 64k * 2
bytes = 128 k bytes.
Um outro aspecto a ser considerado relaciona-se ao método de acesso. Método de
acesso refere-se a como o item deverá ser localizado na memória. Podemos
classificar o método de acesso em quatro tipos:

• acesso sequencial: para acessarmos uma informaçã o (no caso denominado


como registro), devemos percorrer, sequencialmente, todos os registros
anteriores até chegarmos no demandado. Como exemplo de memó ria que utiliza
o acesso sequencial, poderemos relacionar as unidades de fitas magnéticas;
• acesso direto: esse método de acesso é utilizado, por exemplo, nas unidades de
discos. Para se acessar um registro, primeiro pode-se posicionar o dispositivo de
leitura e gravaçã o em uma regiã o específica para que, em seguida, seja possível
realizar um acesso sequencial dentro dessa regiã o. Como é necessá rio um acesso
sequencial, nã o se pode precisar o tempo gasto para acessar um item;
• acesso aleatório: em memó rias com acesso aleató rio, como as memó rias
principais (memó rias RAM – Random Access Memory), a unidade endereçável
pode ser acessada diretamente. Dessa forma, o tempo de acesso é constante e
determinista, independentemente da posiçã o na qual se encontra o item a ser
manipulado;
• memória associativa: na técnica de memó ria associativa, usada, por exemplo,
em alguns modelos de memó ria cache, o item nã o tem um endereçamento
explícito, ou seja, pode estar posicionado em qualquer linha da memó ria. O
processo de busca do item é realizado paralelamente em todas as linhas,
comparando-se os seus conteú dos com um padrã o de bits que representa a
informaçã o demandada.

A tecnologia empregada para o sistema de memória tem um forte impacto sobre a


forma de manipulação das informações, custos e a performance computacional.
Além de impactar diretamente na volatilidade da memória, as tecnologias de
fabricação influenciam na densidade de bits (número de bits armazenados por uma
área). Podemos falar sobre dois grandes tipos principais: as memórias do tipo
DRAM (Dynamic RAM) e as SRAM (Static RAM).
As memórias DRAM são baseadas na utilização de capacitores como elementos
básicos de armazenamento. Porém, os capacitores se descarregam com o tempo,
sendo necessário um ciclo de realimentação para reativar a sua carga (refresh).
Durante o ciclo de refresh, a memória fica bloqueada para leituras e escritas,
deixando-a mais lenta em relação à SRAM.
62

Por sua vez, as SRAM usam componentes semicondutores para o armazenamento


de bits. Isso faz com que as memórias se tornem mais rápidas em relação à DRAM
(pois, além da tecnologia mais rápida, não é necessário o ciclo de refresh). Porém,
ocupa um espaço muito maior para armazenar cada bit da informação.
Todos os aspectos aqui apresentados influenciam no desempenho do sistema de
memória. O desempenho de uma memória está relacionado a três métricas:

• tempo de acesso: o tempo de acesso ou latência representa o tempo, desde a


chegada da requisiçã o ao sistema de memó ria, para que a informaçã o fique
disponível para a transferência;
• tempo de ciclo de memória: período no qual possa ser tratada uma
segunda solicitaçã o sem causar interferências ou danos à s informaçõ es
manipuladas na requisiçã o anterior;
• taxa de transferência: tempo gasto para a completa transferência dos n bits
demandados.

Essas métricas, conceitos e tecnologias podem ser empregados no sistema de


memória, variando dentro de seu nível hierárquico.

3.3.2 Hierarquia de memória e princípios da memória cache

Até o momento, citamos alguns exemplos de locais de armazenamento dentro do


sistema de memória. Mas, como seria o fluxo de informações nesses locais, já que
temos funcionalidades distintas? Lembramos que tudo a ser processado (as
informações e as próprias instruções) deverá ser carregado para os registradores
do processador. E, também, os arquivos executáveis que se encontram no disco
rígido precisam ser transferidos para a memória principal para que sejam
executados. Diante dessas afirmativas, temos a seguinte constituição da hierarquia
de memória:

• registradores: nível mais alto da hierarquia de memó ria. Sã o os elementos de


memó ria internamente ao processador, baseados em componentes
semicondutores;
• memória cache: nível imediatamente abaixo dos registradores. Por se tratar de
uma memó ria de alta velocidade, tem como objetivo diminuir os acessos à
memó ria principal. A memó ria cache pode, ainda, apresentar três níveis: L1 (level
1), L2 e L3. O nível L1, localizado dentro do nú cleo do processador, é sincronizado
com a mesma frequência do nú cleo. Geralmente o nível L1 é dividido entre L1 de
instruçõ es e L1 de dados. O nível L2 encontra-se fora do nú cleo, porém dentro do
encapsulamento do processador. Trabalha com a metade da frequência do nú cleo.
Por ú ltimo, a cache L3 está localizada na placamã e, operando na mesma
frequência do barramento. A cache é implementada, assim como os registradores,
com componentes baseados em semicondutores;
• memória principal: componente de memó ria responsável por conter os
processos em execuçã o. Junto com a memó ria secundá ria, forma a memó ria
virtual (TANENBAUM, 2013). A memó ria principal é implementada, geralmente,
por componentes capacitivos;
63

• memória secundária: representa o nível mais baixo da memó ria (mais distante
do processador). A memó ria secundá ria pode ser exemplificada pelo disco rígido
– dispositivo que usa o meio magnético como forma de armazenamento.

Na medida em que se aumenta o nível, ou seja, aproxima-se do processador,


temse o incremento da performance computacional, diminuição da densidade
(capacidade de armazenamento de menos bits por área de superfície), menor
capacidade de armazenamento, maior custo por bit.
Dentre os níveis da hierarquia de memória, daremos maior foco, nesse momento, à
memória cache devido a sua importância para o aumento da performance
computacional do sistema.
Como mencionado antes, o objetivo da cache é diminuir o número de acessos à
memória principal. Com isso, atenuam-se os atrasos frente à busca ou gravação
das informações junto ao sistema de memória.
O funcionamento da memória cache segue dois princípios: o princípio da localidade
espacial e o princípio da localidade temporal. De acordo com Hennessy (2014),
eles se definem da seguinte forma:

• princípio da localidade espacial: quando um processo usa alguma informaçã o,


a probabilidade de usar outras informaçõ es pró ximas é alta;
• princípio da localidade temporal: a chance de uma informaçã o utilizada
recentemente ser utilizada em um futuro pró ximo é elevada.

Então, a memória cache, usando os princípios dessas duas localidades, armazena


as informações “estratégicas” – tentando-se, dessa forma, evitar acessos
desnecessários à memória principal.

No vídeo “Políticas de Atualização da Cache”, você pode conhecer um pouco mais sobre o funcionamento
da memória cache, a partir dos algoritmos de substituição (UNB-GAMA, 2015):
<https://www.youtube.com/watch?v=1wh5gczKNbc>.

Agora, já temos informações suficientes para nos perguntar: como a cache é


estruturada e organizada? Como as informações são armazenadas e buscadas? A
seguir, responderemos a essas perguntas e algumas outras que poderiam aparecer
em sua mente.

3.4 Elementos do projeto da memó ria cache

Para entender como ocorre a manipulação da memória cache e determinar seu


funcionamento, vamos nos guiar por algumas questões.

• Aonde colocar o item dentro da cache?


• Como localizar a item dentro da cache?
64

• Como realizar as trocas dos blocos armazenados na cache?


• Quais açõ es ocorrem quando o conteú do de um bloco armazenado na cache é
atualizado?

As três primeiras questões serão respondidas quando abordarmos os tipos de


mapeamentos. Por sua vez, a última questão será tratada na política de escrita.

3.4.1 Mapeamento associativo e direto

Antes de prosseguirmos na descrição do tipo de mapeamento, convém mencionar


que a cache manipula blocos de informações (compostos por vários dados ou várias
instruções vizinhas).
O modelo de mapeamento refere-se à localização do bloco dentro da cache. No
mapeamento associativo, um bloco não tem uma posição específica dentro da
cache, ou seja, poderá estar em qualquer linha endereçável. Com essa estratégia, a
cache torna-se mais poderosa, pois permite-se uma maior reutilização das
informações armazenadas. Porém o custo por bit é muito dispendioso pelo fato de
que, em cada linha, deve ser associado um circuito de comparação. A função desse
circuito de comparação consiste em procurar o item solicitado pelo processador
comparando-se o endereço requisitado pelo processador com o conteúdo
armazenado – figura abaixo, item (a).
Para localizar um item solicitado pelo processador, o sistema de gerenciamento da
memória cache acompanha o seguinte fluxo:

• ao receber a demanda realizada pelo processador, todos os circuitos


comparadores realizam a comparaçã o do valor recebido do processador com
todos os conteú dos localizados no campo “tag”;
• o comparador que retornar “true” como resultado da comparaçã o envia um sinal
a um circuito de seleçã o para que o campo “valor” seja acessado;
• será , também, acessado o campo “vá lido” da linha selecionada para que, caso o
conteú do seja vá lido, o conteú do seja despachado para o processador, denotando,
nesse caso, o evento “hit” (hit = conteú do encontrado na cache). Caso o item nã o
seja encontrado, ocorrerá o evento “miss”, fazendo com que seja ativado o nível de
memó ria imediatamente inferior.

Convém salientar que esse procedimento é executado no caso de leituras na


cache. A posição do item no processo de gravação em memória associativa segue
apenas dois critérios:

• caso exista alguma posiçã o vaga, escreva o item nesta posiçã o; • caso contrá rio,
executa-se a política de troca de bloco, que será descrita adiante.

Por sua vez, o mapeamento direto vem em direção contrária aos custos e da
complexidade do hardware – figura a seguir, item (b). A sua estratégia de busca
segue os seguintes passos:

• ao receber o endereço do processador, acessa-se a linha que corresponda à


operaçã o de resto da divisã o do endereço pela quantidade de linhas da cache. Em
65

termos prá ticos, a operaçã o de divisã o é realizada, simplesmente, coletando-se os


n bits menos significativos do endereço. Por exemplo, supondo que o processador
gerou o endereço 35 e que a cache possua oito linhas. Nesse caso, obtém-se a
linha da cache pelos log28 = 3 bits menos significativos. O valor 35(10) poderá ser
expresso como . Nesse caso, a linha a ser acessada é a 3
(011(2) = 3(10)). Como todo bloco a ser alocado nesta linha contém os mesmos n
bits menos significativos, entã o, o campo “tag” precisará armazenar apenas os
(k–n) bits mais significativos, sendo k o tamanho da palavra manipulada pelo
processador;
• na mesma linha, acessa-se o campo “vá lido”. Caso o item seja vá lido, entã o ocorre
o evento “hit”, caso contrá rio, o evento “miss” (de forma aná loga ao que foi
descrito anteriormente).

No caso do mapeamento direto, quando é preciso escrever o item na cache, ocorre


a substituição do conteúdo original pelo novo, demandado pelo processador.
O mapeamento direto tem uma grande desvantagem quando, por exemplo, dois
itens que possuam o mesmo padrão de localização, estejam sendo demandados de
forma alternada – como por exemplo, dois itens acessados durante um laço de
repetição. Neste caso, sempre ocorrerá o evento “miss” pois um item sempre
substituirá o outro. Para atenuar esse problema, existe um terceiro mapeamento
que, na verdade, é a fusão dos dois primeiros: trata-se do conjunto associativo. No
conjunto associativo, item (c) da figura abaixo, ocorre uma replicação das colunas
do mapeamento direto. Nessa abordagem, ao receber uma demanda do
processador, a sistema de cache acessa a linha correspondente como no
mapeamento direto. Com a linha selecionada, aplica-se, para a leitura ou para a
escrita do bloco, os passos como descritos no mapeamento associativo. Esse tipo
de mapeamento é o mais usado nos processadores atuais. Por exemplo, o Intel
Core i7 Haswell utiliza a configuração “8way set associative” (replicação de colunas
com fator 8) em suas caches L1 e L2 (TELES, 2004).
66

Deslize sobre a imagem para Zoom

Figura 7 - Formas de mapeamento da memó ria cache, sendo que em (a) temos o mapeamento associativo, em (b),
o mapeamento direto e, por fim, em (c), o conjunto associativo. Fonte: Elaborada pelo autor, 2018.
Na figura acima, você pode notar o campo “tag” que corresponde à referência do
endereço do bloco armazenado. O campo “válido” tem por objetivo informar se o
conteúdo da linha não pertence a algum processo já finalizado ou algum valor
aleatório produzido no momento da iniciação do sistema.

3.4.2 Política de escrita

Ao se falar sobre política de escrita, podemos referenciar a dois aspectos: quando


um item novo precisa ser gravado ou quando o item é alterado na memória cache.
Quando um item novo é demandado pelo processador e acontece um evento do
tipo “miss”, então significa que o bloco precisa ser lido dos níveis inferiores de
memória e gravado na cache. Sendo assim, os mapeamentos associativos e o
conjunto associativo executam o seguinte algoritmo:

• caso exista posiçã o disponível, salve o item nesta posiçã o;


• caso contrá rio, algum bloco previamente carregado deverá deixar a cache. Mas
qual item escolher? Adota-se um critério de escolha retirando-se, por exemplo, o
bloco que teve o acesso mais remotamente (LRU – Least Recently Used), o bloco
usado com menos frequência (LFU – Least Frequently Used) ou o bloco mais
antigo (FIFO – First In/First Out).

Como mencionamos, o outro aspecto relacionado à política de escrita refere-se


quando há a atualização no valor do conteúdo do bloco presente na cache. Nesse
caso, o sistema de memória pode adotar dois critérios:

• write back: nesse tipo de política, qualquer alteraçã o na cache é repassada aos
níveis inferiores de memó ria, deixando todos os níveis sincronizados com o
mesmo valor de conteú do;
67

• write through: na estratégia de write through, ocorre a atualizaçã o do nível


inferior de memó ria apenas quando o item deixa a cache para ceder espaço a um
novo item demandado pelo processador.
Atualmente, em função do aparecimento dos processadores multicore (vários núcleos), apenas a
política de escrita write through não basta. Supondo a existência de dois núcleos: N1 e N2. Suponha
que um bloco B será usado, inicialmente, por N1, que fará, em seguida, uma atualização de valor.
Usando write through, a modificação realizada em N1 irá refletir, prontamente, nos níveis inferiores
de memória. Nesse momento, suponha que o núcleo N2 utilizará o mesmo bloco B – coletará e
armazenará em sua cache L1 o mesmo valor armazenado nos níveis inferiores na cache L1 de N1.
Porém, em N2, ao modificar o valor de B, fará modificar apenas o valor nos níveis inferiores,
permanecendo o valor na L1 de N1 inalterado. Por consequência, as caches L1 de N1 e N2 ficarão
incoerentes. Diante desse fato, foram criados protocolos de coerência de cache tais como o
protocolo MESI (Modified Exclusive Shared Invalid) e MOESI (Modified Owner Exclusive Shared
Invalid). O Intel Core i7 usa uma variação do MESI (que fora introduzido no Pentium) chamada MESIF
(Modified Exclusive Shared Invalid Forward).

Você pode estar se perguntando: quando se deve usar uma ou outra política de
escrita? Para responder a essa pergunta, abstraia um ambiente que apresenta
apenas um processador que tenha um núcleo. Neste caso, não há nenhuma
possibilidade de que o valor de um bloco seja alterado por outros nós de
processamento. Sendo assim, neste ambiente não é necessário o write through.
Agora abstraia um ambiente que um certo item possa ser buscado por vários
núcleos. O write through ajuda a manter a coerência dos valores armazenados na
hierarquia de memória.

Síntese
Chegamos ao final de mais uma etapa em nosso caminho de conhecimento. Neste capítulo,
passamos pelos aspectos de processamento das instruções, mais especificamente sobre a unidade
de controle do processador e a divisão das instruções em micro-operações. Pudemos ver, também, a
parte de interconexão dos módulos do computador, representada pelo barramento e, ao final, os
conceitos acerca do sistema de memória. Dentro do sistema de memória, pudemos dar um enfoque
maior no sistema de memória cache.

Esperamos que este conteúdo lhe dê condições de tomar decisões nos quesitos relacionados ao
parque de informática da empresa e implementar soluções de forma mais eficiente.

Neste capítulo, você teve a oportunidade de:


• identificar e descrever aspectos referentes à execuçã o das instruçõ es, sob o
ponto de vista da unidade de controle, e à s micro-operaçõ es;
• descrever e interpretar os mecanismos para o tratamento das interrupçõ es;
• situar, esquematizar as funcionalidades e os conceitos relacionados aos
barramentos de interconexã o do computador;
• definir, identificar e reproduzir as técnicas e os modelos usados pelo sistema de
memó ria – mais especificamente, de memó ria cache.

Projeto
68

A IMPORTÂNCIA DO PROCESSADOR E MEMÓRIAS DE ALTO


DESEMPENHO

Equipamentos computacionais de alto desempenho são aplicados em sistemas computacionais


voltados para áreas específicas, como a médica, automação industrial, exploração de petróleo,
sensoriamento remoto, engenharia financeira, mineração de dados, entre outras.

O motivo é a necessidade de ter modelos matemáticos com base em equações complexas,


manipulação de dados em bases com grande volume em conjunto com a semântica desses
mesmos dados.

Sendo assim, é importante ter conhecimento adequado sobre o hardware que será utilizado
para manipular este tipo de informação tão específica e muito comum atualmente.

Vamos praticar

Com a importância do hardware para proporcionar alto desempenho em sistemas


computacionais, é importante que nesta atividade você seja capaz de retrate a importância do
processador, do processamento das instruções, do gerenciamento de memória cache, virtual e
a relação com as novas memórias Crucial de 32 GB da Micron (memórias de alto desempenho).
O seu texto deverá conter uma lauda e deverá discorrer sobre esses temas.

Alguns sites na internet que podem ajudar na busca da resposta:

GAIGARDI, J. O que é a memória virtual? 10 out. 2018. Disponível em:


<https://www.infonova.com.br/artigo/o-que-e-a-memoria-virtual>. Acesso em: 13 set. 2019.

GUIA DO HARDWARE. Processador. 2010. Disponível em:


<https://www.hardware.com.br/termos/processador>. Acesso em: 13 set. 2019.

RIBEIRO, F. Computex: Micron apresenta nova memórias Crucial de 32 GB. 29 maio 2019.
Disponível em: <https://canaltech.com.br/computex/computex-micron-apresenta-
novasmemorias-crucial-de-32-gb-140373>.Acesso em: 13 set. 2019.

UNIVERSIDADE FEDERAL DA PARAÍBA. Ciclo de instrução. s/d. Disponível em:


<http://producao.virtual.ufpb.br/books/edusantana/introducao-a-arquitetura-decomputadores-
livro/livro/livro.chunked/ch02s03.html>. Acesso em: 13 set. 2019.

Ao final, disponibilize sua pesquisa no fórum da seção “Compartilhe”.


69

ARQUITETURA E ORGANIZAÇÃO DE
COMPUTADORES
U 4 - COMO PODEMOS OBTER E ARMAZENAR AS
INFORMAÇÕES E COMO MANIPULÁ-LAS EM
MÁQUINAS CISC, RISC E SUPERESCALARES?

Ednaldo dos Santos

Introdução
Nessa parte dos estudos em Arquitetura e Organização de Computadores, vamos estudar
armazenamento, interfaceamento com o mundo externo, e um pouco mais de processamento.

Para começar, vamos abordar a questão de armazenamento das informações na memória


interna do computador. A partir disso, podemos deduzir a questão inicial: apesar de um
pedaço da cache estar dentro do núcleo do processador, ela pode ser considerada interna,
igualmente à memória principal que está na placa-mãe? Vamos entender isso e também os
conceitos e aspectos físicos destes dois tipos de memória.

Aproveitando o assunto, vamos estudar outro tipo de memória: a ROM (Memória Somente de
Leitura, em inglês, Read Only Memory).

Com esse conhecimento sobre memórias, poderemos avançar para outro questionamento:
como podemos obter dados do mundo externo, usando os dispositivos de entrada e de saída
(E/S)? Essa pergunta será respondida abordando alguns pontos sobre a estruturação e sobre
como podemos manipular os módulos de E/S.

Por fim, entraremos no aspecto de processamento, abordando uma dúvida comum: quais as
diferenças entre os processadores RISC e CISC? A família x86 é, afinal, RISC ou CISC?
Aproveitando o gancho, um outro assunto que estudaremos é em relação aos processadores
superescalares. Você pode, então, ampliar a sua pergunta sobre a família x86: ela é
superescalar? E o que seria superescalaridade?

Esses pontos, sobre RISC, CISC e superescalaridade, serão abordados também neste capítulo.

Com base no conteúdo que veremos a seguir, você terá condições de classificar melhor os
sistemas computacionais existentes, e de solucionar problemas pela adoção de equipamentos
mais específicos para a sua aplicação.

Desejamos bons estudos!

4.1 Memó ria interna


70

O sistema de memória é essencial para um sistema computacional, pelo fato de ser


o responsável por prover o processador com as informações por ele demandadas
(instruções e dados). Ele pode ser dividido em níveis hierárquicos, desde os
registradores (nível mais alto), até a memória secundária (nível mais baixo). Quanto
mais alto o nível da memória, mais rápido é seu processamento, mais cara e menor
a sua capacidade de armazenamento (PATTERSON; HENNESSY, 1998).
A memória interna do computador pode ser classificada em relação ao seu tipo,
volatilidade e tecnologia de fabricação.
Quanto ao tipo de memória, podemos encontrar as de acesso aleatório (RAM –
Random Access Memory) e as ROM (Read Only Memory). Em relação à memória do
tipo RAM, o seu acesso é não sequencial, ou seja, podemos acessar um certo
conteúdo, em qualquer localização, por intermédio da passagem de um endereço.
Por exemplo, é possível ingressar no conteúdo de um vetor cuja célula é
endereçada pelo índice. Por sua vez, as memórias do tipo ROM são aquelas
representadas por sua capacidade apenas de atender às requisições de leitura.
Veremos, nessa seção, a memória interna em sua concepção mais física. Essa
memória interna será classificada, aqui, como memória dinâmica (DRAM), memória
estática (SRAM) e memória apenas de leitura (ROM).

4.1.1 Memória DRAM e SRAM – RAM dinâmica e estática

Antes de começarmos a falar sobre as memórias do tipo DRAM e SRAM, vamos


dar uma visão geral da interface de um módulo de memória. Basicamente, um
módulo de memória poder ser representado na figura abaixo:

Deslize sobre a imagem para Zoom

Figura 1 - Mó dulo bá sico de memó ria. Outros pinos poderã o ser encontrados nas implementaçõ es reais de memó ria.
Fonte: Elaborada pelo autor, 2018.
Na figura acima, temos uma possível pinagem de um módulo de memória. Nesta
memória hipotética, podemos encontrar os seguintes pinos:
71

o endereço: palavra produzida pelo processador que contém a


localizaçã o da memó ria a ser acessada;
o operação (W/R): define a operaçã o a ser realizada. Neste caso, a
linha sobre o caracter “W” indica que, caso esse pino receber o
valor zero, será realizada uma operaçã o de escrita (“W”: write).
Caso contrá rio, ou seja, se esse pino tiver o valor um, foi
demandada uma operaçã o de leitura (“R”: read);
o habilitação: esse pino, também chamado como “enable”, habilita a
memó ria a proceder a operaçã o. Esse pino existe, pois a pinagem
relativa ao endereço é ligada ao barramento compartilhado. Sendo
assim, no barramento trafegarã o sinais envolvendo os dispositivos
e E/S. Assim, o pino enable (quando ativado) informa, mó dulo de
memó ria, que o sinal de endereço é destinado à pró pria memó ria;
o dados: os pinos “dados” representam as informaçõ es que serã o
entregues ou coletadas da memó ria. Você pode notar que, ao
contrá rio dos demais, esses pinos sã o bidirecionais;
o clock: por fim, esse pino entrega o pulso de clock para a
sincronizaçã o das açõ es realizadas pela memó ria para proceder a
açã o de leitura ou gravaçã o das informaçõ es.

As memórias do tipo RAM podem ser diferenciadas em relação à tecnologia de


fabricação e suas utilidades principais. Com os dois tipos de memória RAM, a
dinâmica (DRAM), e a estática (SRAM), faremos uma pergunta de provocação:
porque a DRAM é usada na memória principal e a SRAM é usada na cache (níveis
L1 e L2, principalmente)? A resposta está relacionada com a tecnologia de
fabricação.
A figura abaixo, ilustra a concepção básica de uma DRAM e de uma SRAM.
72

Deslize sobre a imagem para Zoom

Figura 2 - Estrutura bá sica de uma cé lula de memó ria. Em (a), tem-se uma célula da DRAM e, em (b), uma
configuraçã o bá sica da SRAM. Fonte: STALLINGS, 2010, p. 130.

Na figura acima, observa-se, em (a), integrando uma célula de memória DRAM, um


componente eletrônico denominado “capacitor”. Um capacitor tem a capacidade de
armazenar energia temporariamente. No caso da memória, essa carga armazenada
é o próprio bit armazenado. Porém, como mencionado, a carga do capacitor é
temporária (mesmo que o circuito continue recebendo tensão de alimentação).
Esse é o motivo deste tipo de memória ser chamada de dinâmica.
Em função da descarga do capacitor, antes dele perder a referência do bit
armazenado, o circuito de memória precisa ser “relembrado” (refresh). De tempos
em tempos, ocorre o evento de refresh da memória (o tempo é em função da taxa
de refresh). Durante todo o ciclo de refresh, a memória fica bloqueada tanto para
operações de escrita, quanto para operações de leitura. Esse bloqueio impacta, de
forma negativa, diretamente na performance das operações de memória. Por outro
lado, memórias SRAM, item (b) da figura acima, a base para a sua implementação
são componentes baseados em semicondutores (transistores). Ao contrário da
memória DRAM, seu armazenamento ocorre de forma estática, enquanto houver
alimentação suprindo-a de energia.
Em função da implementação com transistores ocupando mais espaço, a memória
SRAM se torna menos densa em relação à DRAM (menos quantidade de bits por
área). Além da densidade, podemos falar que a SRAM é mais rápida e apresenta
um custo mais alto (STALLINGS, 2010).
73

Você tem dúvidas sobre as diferenças entre as memórias DDR3 e DDR4 e qual a melhor escolha para a
montagem dos computadores? Assista o vídeo que vai te ajudar a diferenciar as memórias:
<https://www.youtube.com/watch?v=Ual7ELvPsJc>.

Atualmente, encontramos memórias DRAM do tipo SDRAM (DRAM Síncrona –


Synchronous DRAM), equipando os computadores. Uma SDRAM é uma memória
híbrida, sincronizada pelo clock do sistema computacional, envolvendo a DRAM e a
SRAM (TANENBAUM, 2013). A grande vantagem da SDRAM, frente à DRAM é a
possibilidade de eliminação de sinais de sincronização entre a memória e o
processador – a sincronização é feita somente com os pulsos de clock. Este artifício
permite que a memória opere no modo rajada (burst), no qual a memória pode
transmitir dados com endereçamentos subsequentes, sem a intervenção do
processador em enviar os próprios endereços demandados. Com isso, permite-se
um melhor aproveitamento do pipeline, pois há a maior probabilidade de deixá-lo
cheio.

Você sabia que existem memórias flash do tipo NOR e do tipo NAND? Para saber
mais, recomendamos o especial da revista Guia do Hardware (MORIMOTO, 2007),
sobre memórias: <https://www.hardware.com.br/static/media/RevistaGDH_04.pdf>.

A evolução da memória SDRAM culminou nas memórias SDRAM DDR (SDRAM


Taxa Dupla de Dados – SDRAM Dual Data Rate). Neste tipo de implementação, a
memória consegue entregar dois dados a cada ciclo de clock, um na subida da
onda de clock, e outro na descida.

4.1.2 Tipos de ROM e correção de erro

Um outro tipo de memória interna, que encontramos nos computadores, é a


memória tipo ROM. Esse tipo de memória, não volátil, é utilizada em ocasiões nas
quais requer apenas operações de leitura, como por exemplo: bibliotecas de
funções, para que sejam usadas frequentemente (tal como BIOS – Basic
Input/Output System), tabelas de funções ou informações fixas a serem
demandadas pelo sistema computacional. Nesse ponto, você pode estar
perguntando: mas, se é apenas de leitura e pode conter código (instruções), como
foi feita a gravação das instruções na ROM? A memória ROM pode ser classificada
em relação ao momento no qual poderá ser realizada a gravação, da seguinte
forma (STALLINGS, 2010):

o ROM – no tipo ROM original, as instruçõ es eram gravadas no


momento da fabricaçã o do chip;
o PROM (ROM programável – Programmable ROM) – a escrita, neste
caso, poderá ser realizada uma ú nica vez. Para tanto, será
necessá rio um ambiente de programaçã o que possua uma interface
74

física (por exemplo, usando um cabo serial) para que seja realizada
a programaçã o do dispositivo;
o EPROM (PROM apagável – Erasable PROM) – semelhante à PROM,
porém permite vá rias gravaçõ es. Para se gravar um novo conjunto
de informaçõ es (dados ou có digo), é necessá rio realizar a etapa de
apagamento, submetendo o dispositivo a um banho de luz
ultravioleta. Neste tipo de componente, existe, no invó lucro, uma
regiã o translú cida para permitir que a luz ultravioleta atinja a
regiã o interna do componente;
o EEPROM (PROM apagável eletricamente – Electrically Erasable
PROM) – igualmente à EPROM, permite o apagamento das
informaçõ es para que seja feita uma nova gravaçã o. Porém, em vez
de se utilizar luz ultravioleta, o processo de apagamento se faz
mediante sinais elétricos.

Você sabia que o BIOS (Sistema Básico de Entrada e Saída – Basic Input-Output
System) foi criado a mais de 25 anos e ainda persiste nos computadores? Existe uma
proposta para substituir o BIOS, chamada de UEFI ( Unified Extensible Firmware
Interface, em português, Interface Unificada Extensível para o Firmware) (PACHECO,
2010). Maiores detalhes no artigo: <https://www.hardware.com.br/artigos/bios/>.

Quando se fala em armazenamento de informações e transmissão de dados, na


maioria das vezes, temos que nos preocupar com a corretude da informação
armazenada/transmitida. Corretude, neste caso, significa detectar ou, até mesmo,
corrigir os dados em caso de erros.
Erros (ou falhas) podem ser permanentes ou transientes. Falhas permanentes
ocorrem por falha física do componente – ocasionadas por defeitos de fabricação
ou deterioração do material pelo tempo de uso. Falhas transientes também podem
ser causadas pelo desgaste do material em função do tempo do uso ou, ainda, por
influência de interferências externas.
Independentemente da causa ou tipo de falha, temos a necessidade de verificar se
a informação que foi armazenada ou transmitida encontra-se coerente com os
dados originais.
Um dos mecanismos mais simples consiste no cálculo do bit de paridade. Chama-
se paridade par quando se adiciona, à palavra, o bit 1 para que a quantidade total
de bits com valor 1 seja par (ou paridade ímpar para completar a quantidade ímpar
de bits iguais a 1).
Por exemplo, caso a palavra a ser armazenada seja . Como, na palavra,
temos 5 bits iguais a 1, adiciona-se um nono bit com valor 1 para completar a
quantidade par – neste caso, armazena-se . Por outro lado, caso
tivéssemos a palavra (que já apresenta um número par de bits iguais a
um), adicionaríamos o bit zero, ficando . O bit de paridade par é
75

conseguindo aplicando-se o operador “ou exclusivo” (XOR) em todos os bits da


palavra.
Porém, caso a interferência atingisse dois bits e não somente um, o que
aconteceria?
Vejamos alterando-se dois bits do primeiro
exemplo, passando para
. . O bit de paridade par continuaria sendo
de um (
). Neste caso, a utilização de bit de paridade não é muito seguro.
Dependendo do ambiente e necessidade, usa-se algum outro método de detecção
de erros, com é o caso do código de Hamming.

Richard Wesley Hamming (1915-1998), foi um matemático nascido nos Estados Unidos, que marcou seu
nome na ciência da computação, com o chamado código de Hamming. O código é usado para detecção e
correção de erros, não somente frente ao armazenamento das informações mas, também, no mundo das
telecomunicações. Para saber mais, leia a tradução de um texto do livro “The Art of Doing Science and
Engineering” (HAMMING, 2016): <http://www.de.ufpe.br/~hmo/TraducaoHamming.pdf>.

O código de Hamming permite não somente a detecção da ocorrência de erros,


mas, também, que os dados sejam corrigidos. A ideia central baseia-se na
formação de subconjuntos com intersecções. A partir dos bits de paridade destas
intersecções, consegue-se verificar a ocorrência e corrigir os erros ocorridos sobre
a palavra de informação (STALLINGS, 2010).

4.2 Sistemas de entrada e saída


Além do processador, memória e barramento, fazem parte, também, do
computador, os sistemas de entrada e de saída (E/S – I/O – Input/Output).
Sistemas de E/S tem por objetivo interfacear com dispositivos externos, tais como
vídeo, teclado e disco rígido.
Você pode estar se perguntando: como o computador consegue manipular dados
provenientes de um dispositivo que opera blocos (registros), como os discos
rígidos, e também de dispositivos que transmitam suas informações de forma serial,
como os dispositivos ligados a uma porta USB (Universal Serial Bus)? Podemos
responder que os dispositivos não estão ligados diretamente ao barramento e, sim,
são interfaceados por um módulo de E/S, também chamado de controlador de E/S.
Nesta seção, vamos falar sobre os módulos de E/S e as suas formas de
processamento.

4.2.1 Estrutura do módulo de E/S

Os módulos de E/S devem ser implementados de forma a exportar funcionalidades


de interfaceamento entre o barramento e os próprios dispositivos de E/S, sob sua
responsabilidade. A figura abaixo ilustra o interfaceamento básico de um módulo de
E/S.
76

Deslize sobre a imagem para Zoom

Figura 3 - Estrutura bá sica de um mó dulo de E/S, identificando seus componentes externos e suas interfaces para a
interligaçã o com o barramento. Fonte: STALLINGS, 2010, p. 130.

Na figura acima podemos ver a estrutura básica de um módulo de E/S. Nela,


notamos os pinos de interfaceamento com o barramento (linhas de dados,
endereço e de controle) e o interfaceamento com os dispositivos propriamente
ditos. Também identificamos as linhas de endereço que transmitem a identificação
do módulo de E/S gerada pelo processador. A partir de seu conteúdo, o módulo
verifica se a requisição é ou não direcionada a ele. Veremos, adiante, que um
módulo pode ser identificado como um endereço de memória, ou como um
identificador próprio de E/S. Por sua vez, os registradores de estado/controle
armazenam as condições atuais do módulo, por exemplo, se ele se encontra
ocupado ( ), pronto para receber novas demandas ( ) ou, ainda, informar
estados de erro. Por fim, as linhas de controle são responsáveis pelo envio das
requisições realizadas pelo processador ou usados quando solicitadas operações
envolvendo DMA (Direct Memory Access, em português, acesso direto à memória) –
que será visto adiante.
A unidade de lógica de E/S desempenha a função de gerenciamento dos
dispositivos de E/S além de ser o módulo responsável pelo recebimento das
requisições (pelas linhas de controle e de endereço) e instanciações ou
recebimento das informações por meio dos registradores de dados e de
estado/controle.
Como funcionalidades dos módulos de E/S podemos citar (STALLINGS, 2010):
77

o controle e temporizaçã o: o controle e temporizaçã o sã o


funcionalidades fundamentais para permitir a sincronizaçã o de
acesso e uso dos dispositivos sob a coordenaçã o do mó dulo de E/S;
o interaçã o com o processador e com os dispositivos de E/S: a
interaçã o com o processador permite o recebimento das demandas
(representadas por sinais e de palavras de controle) e, também,
permite o envio ou o recebimento das informaçõ es a serem
manipuladas. Essa demanda é completada pela ativaçã o dos
dispositivos de E/S para a coleta ou envio dos dados perante o
mundo externo;
o detecçã o de erros: já que os dispositivos de E/S envolvem
armazenamento e transmissã o, como mencionado anteriormente,
necessitam, na maior parte dos casos, de mecanismos para
detecçã o de erros;
o bufferização das informaçõ es sob manipulaçã o: a técnica de
armazenar temporariamente (bufferizar) uma informaçã o, permite
compatibilizar as taxas de transferência entre os dispositivos e os
barramentos envolvidos, uma vez que os dispositivos de E/S
tendem a ser mais lentos em relaçã o ao barramento e ao
processador.

Mais especificamente em relação à funcionalidade de controle e temporização,


podemos nos atentar ao fato de que o mecanismo para acesso ao dispositivo de
E/S é baseado no handshake. Tal mecanismo é dividido em duas fases: inicialmente,
o processador consulta ao módulo de E/S para verificar a disponibilidade de um
dispositivo. Caso haja uma resposta positiva, então, somente neste momento, é
que o processador envia um comando de E/S para efetivar a transferência das
informações.
Convém salientar que a comunicação entre o processador e o módulo de E/S
requer o uso do barramento. Sendo assim, deve-se, ainda, seguir a sincronização
imposta pelo árbitro do barramento, para consumar a comunicação entre o
processador e o módulo de E/S.
Há uma diferença entre um canal de E/S (ou processador de E/S) e um controlador
de E/S (ou controlador de dispositivo). Os canais de E/S, usados normalmente em
computadores de maior porte (exemplo, os mainframes), são módulos com um grau
de independência elevado e a sua complexidade permite que eles assumam
grande parte do processamento inerente à coleta ou transmissão de informações
junto aos dispositivos de E/S. Os controladores de E/S, encontrados geralmente
nos computadores pessoais, são módulos primitivos e requerem maior controle por
parte do processador (STALLINGS, 2010).
Mas, como, efetivamente, os módulos de E/S são manipulados? A seguir,
abordaremos esse assunto.

4.2.2 Instrução de E/S e processamento de E/S

Para que possamos manipular os módulos de E/S devemos, primeiro, saber o


modo de manipulação do módulo em específico. Três formas são admitidas: E/S
programada, E/S controlada por interrupções e DMA (Acesso Direto à Memória –
78

Direct Memory Access). Nos dois primeiros modos, o processador intermedeia a


transferência de informações entre o módulo de E/S e a memória. Já, no último
modo (DMA), a transferência para a memória é realizada diretamente pelo módulo
de E/S. A figura a seguir, mostra fluxogramas destes três tipos de manipulação para
que, depois, possamos explanar sobre o assunto.

Deslize sobre a imagem para Zoom

Figura 4 - Fluxogramas relacionados aos trê s modos de manipulaçã o dos mó dulos de E/S: programada, controlada
por interrupçã o e DMA. Fonte: STALLINGS, 2010, p. 130.

Observando a figura acima, você pode perguntar: mas, praticamente não há


diferença entre o modo de E/S programada e o modo baseado em interrupção? No
fluxograma existe uma sutil diferença, mas, na prática, essa sutil diferença
representa uma boa economia de consumo computacional. Para sanar essa
dúvida, vamos explicar cada um dos modos.
No primeiro modo, na E/S programada, há a necessidade de utilizarmos instruções
de acesso ao módulo. Essas instruções variam em função do tipo de mapeamento
de adotado pelo computador em questão, ou seja, existem processadores que
fazem com que o módulo de E/S seja acessado como se fosse uma posição de
memória enquanto outros necessitam de operações especiais tais como:
e (instruções de C ANSI). Nesta última forma de acesso, os
módulos são endereçados como portos de E/S.
79

Às vezes, para acessar dispositivos de E/S, há a necessidade de se escrever um device driver. No artigo
“Aprendendo a escrever drivers para o Linux” (SCHARDONG, 2012), você tem uma orientação inicial:
<http://www.jack.eti.br/aprendendo-a-escrever-drivers-para-o-linux/>.

Porém, independentemente do tipo de acesso (mapeamento como memória ou


porto de E/S), há a necessidade de se verificar, constantemente, o estado do
módulo até que ele se encontre pronto para ser operado. Traduzindo essa
afirmação em linha
de código teremos: " ;"
Nota-se que o laço de repetição é vazio (sem nenhuma instrução a ser realizada).
Isso denota a “espera ocupada”, ocupando recurso computacional sem realizar um
processamento efetivo.
Para evitar a espera ocupada, pode-se adotar o modelo no qual o módulo de E/S é
controlado por interrupção. Neste tipo de modelo, a programação consiste em ativar
uma interrupção para que seja acessado o módulo de E/S requerido. A requisição é
enfileirada pelo processador de interrupções que a atenderá assim que o
dispositivo estiver pronto.
Como essas operações envolvem apenas sinais, não há a necessidade de ter um
trecho de código que teste continuamente o estado de dispositivo ocupado. Porém,
os dois modos descritos têm o inconveniente de requerer, continuamente, a
intervenção do processador para proceder a transferência de informações entre a
memória e o módulo de E/S. Essa necessidade é eliminada quando é utilizado o
modo DMA.
No modo DMA, retira-se a responsabilidade de gerenciar a transferência das
informações entre o módulo de E/S e a memória. Neste caso, há somente a
intervenção do processador para configurar o controlador de DMA e, depois,
somente quando recebe, do controlador de DMA, o sinal indicando a finalização da
transferência. A figura a seguir ilustra um módulo básico de DMA.
80

Deslize sobre a imagem para Zoom

Figura 5 - Mó dulo bá sico de DMA. Nota-se a presença das linhas de dados, de endereço e de controle (divididas em
linhas específicas para a ló gica de controle). Fonte: STALLINGS, 2010, p. 192.

Na figura acima, temos as linhas de dados sendo utilizadas em dois momentos


distintos: na configuração do DMA e na transferência efetiva das informações. Na
etapa de configuração, o processador envia, para o DMA, a quantidade de bytes a
ser transferida, o endereço inicial da fonte das informações e do destino na
memória principal. Após este momento, durante o decurso da transferência, as vias
servirão para o transporte efetivo das informações (os dados são disponibilizados
pelo DMA pelo registrador de dados).
As linhas de endereço serão utilizadas, também, no momento da transferência, de
modo que o sistema de memória possa receber a localização na qual escreverá os
dados transferidos.
Em relação aos sinais de controle, destacam-se aqueles relacionados à
interrupção, pois o DMA também é baseado na utilização de interrupções para o
seu funcionamento e interfaceamento com o processador. Interrupções que
ocorrem durante a reivindicação do processador ao controlador do DMA e, também,
no momento do término de transferência – para que o DMA possa sinalizar para o
processador.
Todos esses modos e técnicas precisarão ser lembrados no momento em que você
tiver a necessidade de implementar, quando necessário, métodos de acesso aos
dispositivos de E/S – seja utilizando interfaces padrões como USB, FireWire e
InfiniBand, ou algum outro dispositivo implementado para uma finalidade bem
específica.
81

4.3 Evoluçã o dos computadores RISC/CISC

Os processadores podem ser classificados em relação à arquitetura e à


organização. Esses dois modos de abstração possuem um elemento em comum: o
seu conjunto de instruções.
O projeto do conjunto de instruções permite definir um processador como sendo
CISC (Complex Instruction Set Computer, em português, Computador com Conjunto
de Instruções Complexas) ou RISC (Reduced Instruction Set Computer, em
português, Computador com Conjunto de Instruções Reduzidas), o que impacta
diretamente sua organização como por exemplo, a estrutura de seu pipeline.
Alguns pontos são primordiais na diferenciação dos computadores baseados na
metodologia CISC, ou RISC. Dentre os quais, podemos mencionar, em relação ao
RISC (STALLINGS, 2010):

o banco de registradores envolvendo um nú mero maior de GPRs


(General Purpose Registers, em português, Registradores de
Propó sito Geral). A quantidade maior de registradores permite
uma maior otimizaçã o de seu uso – seja pela maior probabilidade
de reaproveitamento de valores previamente carregados, ou seja,
pela possibilidade de usar o renomeamento de registradores em
caso de hazards de dados;
o conjunto de instruçõ es simples: as instruçõ es de uma má quina
RISC sã o simples. Sendo simples, pode-se aproveitar melhor os
conceitos inerentes ao sistema de pipeline;
o otimizaçã o de pipeline: devido à s pró prias características das
instruçõ es, o pipeline pode ter sua otimizaçã o feita de forma mais
agressiva;

Com base nestas afirmativas, abordaremos, a seguir, as características da


execução e conceitos que cercam o modelo RISC.

4.3.1 Características da execução das instruções

Como mencionado, uma das características do modelo RISC é o fato de seu


conjunto de instruções contemplar instruções mais simples (reduzidas). Para que a
concepção do processador RISC fosse idealizada, alguns levantamentos foram
feitos para que a ISA (Instruction Set Architecture, em português, Arquitetura de
Conjunto de Instruções ) fosse projetada. Tais levantamentos referiram-se a:

o frequência de uso das operações: o índice permitiu consolidar


quais operaçõ es necessitariam mais otimizaçõ es e como ficaria o
relacionamento do processador com o sistema de memó ria. O
referido índice permitiu, também, estudos sobre o emprego de
superescalaridade nos processadores RISC;
82

o frequência de uso dos operandos: essa métrica permitiu que o


sistema de memó ria fosse projetado, incluindo a estimativa de
tamanho e os mecanismos associados ao banco de registradores e
memó ria cache;
o sequência de execução das instruções: a aná lise da sequência
permitiu um estudo mais aprofundado da estrutura do pipeline.

Os levantamentos citados acima foram essenciais, não somente para a concepção


do conjunto de instruções do processador RISC mas, também, para otimizações do
pipeline e do sistema de memória (em relação ao banco de registradores e memória
cache). Resumindo, podemos falar que pipeline e o sistema de banco de
registradores são os elementos que mais contribuem com a performance dos
processadores RISC.
Falando em banco de registradores, convém lembrar que, quanto mais se
consegue reaproveitar as informações previamente nos registradores, melhor será
o desempenho do processador pois atenua-se o número de acessos ao sistema de
memória. Para permitir uma otimização, existem duas abordagens uma baseada
em software e outra baseada em hardware.
Na abordagem de software, há a necessidade do compilador realizar uma análise
do programa, de modo que os registradores sejam usados mais massivamente,
armazenando as variáveis que serão mais utilizadas.
Um exemplo de abordagem de hardware consiste na utilização de janelas de
registradores. Para explicarmos sobre janelas de registradores, vamos imaginar a
estrutura de um programa diferenciando as variáveis locais e globais. Imaginemos,
também, passagem de parâmetros, quando uma função evoca outra. Para
continuarmos na explanação, vamos supor, ainda, que o programa possui quatro
funções (procedimentos) que serão chamadas sequencialmente, ou seja, função
evoca a função , que evoca a função , e assim por diante. A figura abaixo ilustra
a janela de registradores envolvendo essas quatro funções.
83

Deslize sobre a imagem para Zoom

Figura 6 - Exemplo de janelas de registradores sendo usadas por quatro funçõ es aninhadas. A funçã o A passa
parâ metros para a funçã o B, e assim por diante. Fonte: STALLINGS, 2010, p. 402.

Na figura acima vemos a alocação de uma janela para cada função. Na medida em
que as funções vão sendo chamadas, ocorre a alocação de uma janela (de forma
sequencial) para que possam ser armazenadas as variáveis locais de cada função.
A transição das janelas é usada para armazenar os valores relativos aos
parâmetros passados de uma função para outra.
No momento do retorno, na finalização de uma função, a janela ativa volta a ser a
antecessora. Dessa forma, as variáveis não são perdidas e, consequentemente,
não precisam ser buscadas, novamente, junto à memória.
No caso das janelas de registradores, listamos algumas perguntas que podem
surgir.

o E se tivermos muitas chamadas aninhadas de funçõ es e chegarmos


ao limite do nú mero de janelas? O que acontece com as variáveis
que estavam armazenadas, relativas à s funçõ es mais antigas? Neste
caso, há o uso da memó ria cache para armazenar as variáveis mais
antigas.
o O uso das janelas de registradores nã o é ineficiente, pois vá rios
registradores poderã o ficar ociosos? Para responder a esta
pergunta, vamos comparar com a cache. A cache manipula blocos
de informaçõ es. Em alguns (ou vá rios) momentos, será necessá rio
manipular apenas uma variável dentro do bloco, ou seja, todas as
84

demais informaçõ es serã o carregadas “à toa”. Entã o, poderemos ter


uma ociosidade de uso na cache. Na janela de registradores, a
unidade de manipulaçã o é a pró pria variável (e nã o blocos)
podendo ter registradores nã o alocados. De uma forma ou de outra
(nas janelas de registradores ou na cache) temos ociosidade, ou de
registradores nã o alocados, ou de itens carregados na cache e nã o
utilizados.

As janelas de registradores atuam como um buffer circular, no qual as janelas


podem ser sobrepostas. Diante disso, a otimização de uso se faz com base nas
características encontradas nas linguagens de alto nível, ou seja, o uso frequente
de chamadas de procedimentos. Por conclusão, é por esse motivo que os
levantamentos descritos no início dessa seção foram essenciais para o
desenvolvimento da concepção da ideia que envolve os processadores RISC.

4.3.2 Instruções reduzidas

Como já mencionado, máquinas RISC tem como principal característica, o fato de


possuírem, em sua implementação, instruções reduzidas. Instrução reduzida
significa instrução simples, otimizada. Temos quatro características básicas de uma
instrução reduzida (STALLINGS, 2010):

o o tempo de execuçã o de uma instruçã o corresponde a um ciclo de


má quina. Ciclo de má quina representa o tempo necessá rio para o
acesso e coleta de informaçõ es, junto aos registradores, executar
uma operaçã o e escrever o resultado junto ao banco de
registradores;
o as operaçõ es sã o do tipo registrador-registrador, ou seja, nã o
existem instruçõ es que misturem registrador-memó ria, exceto
aquelas de carga e escritas na memó ria;
o os modos de endereçamento sã o simples, nã o possuindo, por
exemplo, endereçamento indireto;
o utilizaçã o de formatos simples de instruçõ es é essencial para se
projetar unidades de controle mais simples, nas quais o processo
de decodificaçã o e busca dos operandos, torna-se mais á gil, em
funçã o da menor complexidade do hardware.

É constante a comparação, para saber qual a melhor tecnologia: CISC ou RISC? Cada uma apresenta
pontos vantajosos sobre a outra. Por exemplo, processadores RISC tem uma implementação mais
simples, consomem menos energia e fazem uso mais eficiente de seu pipeline e do banco de
registradores. Processadores CISC conseguem manipular, de forma mais eficiente, instruções
complexas. Mas, então, por que não juntar os dois modelos?
85

Pensando nisso e na compatibilidade em relação a modelos anteriores, a família x86 passou a adotar,
desde o Pentium Pro (1995), o modelo híbrido. Esse processador era um CISC dotado de um núcleo
RISC. Na ocasião, o processador contava com decodificadores responsáveis pela conversão de
instruções complexas para sequências de instruções simples. Com isso, introduziu-se, também, a
execução fora de ordem.

Atualmente, praticamente todos os processadores que equipam computadores pessoais adotam o


modelo híbrido RISC/CISC. Você pode ler mais sobre as metodologias e esse hibridismo no artigo
(CARVALHO, 2017): <https://pt.linkedin.com/pulse/arquitetura-de-computadoresdiferen%C3%A7a-
entre-risc-e-carlos-eduardo>.

Todas essas características do RISC permitem que o pipeline também seja


otimizado, assim como as interfaces internas e externas do processador. Isso
favorece a simplicidade do circuito como um todo, pois são necessários, por
exemplo, menos elementos de roteamento interno de informações. Como exemplo
de processadores RISC, podemos citar: SPARC, MIPS R4000 e micro-RISC e
ARM. Processadores que adotam padrão RISC são mais empregados em sistemas
embarcados e aplicações industriais e em tempo real, pois são mais deterministas
em relação ao tempo de processamento das instruções.

4.4 Má quinas escalares e superescalares


Quando se fala em pipeline, uma das maiores preocupações é tentar mantê-lo
cheio, para obter a máxima vazão (throughput) de processamento das instruções.
Em máquinas escalares, que carregam a possibilidade de executar apenas uma
instrução por vez, o pipeline pode não ser atendido plenamente, devido aos
conflitos e dependências (hazards) de dados, estrutural, ou de controle.
Para se resolver esse problema, devemos ter mecanismos que possam antecipar
instruções que estejam aptas a serem executadas, invertendo a ordem daquelas
que devem esperar para que alguma dependência seja resolvida. Essa técnica é
chamada execução fora de ordem e, para se conseguir, devemos adotar
mecanismos que permitam o paralelismo em nível de instruções (ILP – Instruction
Level Parallelism).
Uma das técnicas existentes para se chegar ao ILP é a adoção da
superescalaridade. Superficialmente falando, superescalaridade consiste na
replicação das unidades funcionais.

No artigo “Arquiteturas Superescalares” (FREITAS, 2016), podemos entender mais sobre as principais
limitações que ocorrem na execução paralela de instruções na arquitetura. Também podemos conhecer
os principais processadores de mercado com arquitetura superescalar, para aprofundar nossos estudos.
Leia o artigo completo:
<http://www.ic.unicamp.br/~rodolfo/Cursos/mo401/2s2005/Trabalho/029043superescalar.pdf>.

Vamos mais a fundo em superescalaridade, para entender alguns outros aspectos


relacionados ao paralelismo em nível de instruções.
86

4.4.1 Características
A motivação principal para o desenvolvimento de arquiteturas superescalares
consiste na possibilidade de se executar instruções de forma paralela. Para tanto,
são replicadas unidades funcionais, sendo que, cada uma, apresenta o seu próprio
pipeline.
A figura abaixo, ilustra uma implementação de um processador superescalar típico.

Deslize sobre a imagem para Zoom

Figura 7 - Estrutura de um processador superescalar típico. Nota-se a presença de unidades funcionais


replicadas. Fonte: STALLINGS, 2010, p. 430.

Como podemos perceber na figura acima, a existência de unidades funcionais


replicadas dotadas de pipeline, faz com que haja a possibilidade de se executar
instruções independentes de forma paralela, o chamado ILP.
Sabemos que o ILP permite a execução fora de ordem. Mas, detectar as
dependências de forma que possa “pular” instruções impossibilitadas de serem
executadas? Como fazer com que as dependências sejam eliminadas, em alguns
casos?
Para responder às questões acima, vamos citar alguns mecanismos adotados pelos
processadores atuais.
O primeiro mecanismo que podemos mencionar consiste na separação dos bancos
de registradores. Como podemos ver na figura anterior, há a separação do banco
de registradores para atender as operações que envolvem dados inteiros e as que
envolvem dados de ponto flutuante. Essa abordagem já atenua a frequência de
hazards estruturais, devido à possibilidade de dois acessos simultâneos aos
registradores.
Dependências de controle podem ser atenuadas com a previsão de desvio. Ao se
deparar com uma instrução de desvio, o processador tenta prever qual será a
próxima instrução: a que inicia o bloco do desvio tomado, ou a que inicia o bloco do
desvio não tomado? Para tentar manter a eficiência computacional, ele toma uma
87

decisão com base no histórico do processamento. Caso a decisão seja acertada, a


instrução é efetivada. Caso contrário, descarta-se os resultados obtidos pelas
instruções executadas erroneamente.
Para encaminhar as instruções para as unidades funcionais, adota-se a emissão
múltipla de instruções. A unidade de despacho é capaz de coletar um bloco de
instruções e armazená-las em um buffer, chamado de janela de execução.
Após uma decodificação e análise de dependências, as instruções contidas na
janela de execução são direcionadas aos módulos funcionais correspondentes.
Como a emissão, nos processadores superescalares pode ser realizada fora de
ordem, há a necessidade de efetivar os resultados respeitando-se a ordem original
de forma que os resultados sejam ordenados.
Os resultados podem ser efetivados pela ação do evento de conclusão (commit) ou
refutados – no caso, por exemplo, daquelas envolvidas em instruções de desvios
tomados erroneamente pela previsão de desvios.
Por fim, no caso de conflitos em relação à geração de valores, pode-se adotar o
renomeamento de registradores (HENNESSY; PATTERSON, 2014). Para tanto,
vamos supor o seguinte código:

No código acima, podemos notar a presença de alguns conflitos e dependências. A


linha (ii) depende o resultado obtido na linha (i). Por sua vez, a linha (iv) depende
de (iii). Mas, como as instruções poderão ser despachadas simultaneamente, ou
com uma defasagem mínima de tempo, devemos considerar que, como a operação
da linha (i) é uma divisão, ela demorará mais tempo a ser executada em relação às
demais. E se ela finalizar a produção de “a”, logo após a geração de “a” pela linha
(iii), qual o valor a ser usado na linha (iv): o “a” obtido da linha (i), ou o da linha (iii)?
Para evitar essa dúvida, usa-se, como alternativa, o renomeamento de
registradores.
No caso específico, troca-se o registrador " ", da linha (iii), e todos os
subsequentes, por outro registrador. No exemplo adotado, ficaria:

Com o renomeamento, este tipo conflito é eliminado, porém aumenta-se a


complexidade do processador pelo fato de ter a necessidade de possuir uma tabela
88

que fizesse o relacionamento entre a referência original do registrador e o resultado


do renomeamento.

4.4.2 Tendências
Como você pode notar, estamos em uma ascensão em relação ao uso de
paralelismo nos computadores. Historicamente, tivemos como ponto de partida, a
introdução do pipeline, que representa um pseudoparalelismo. Na sequência, houve
a incorporação da superescalaridade, adicionando, de fato, o paralelismo para
dentro dos processadores.
Porém, a tendência é que não fiquemos limitados ao paralelismo em nível de
instrução, mas, sim, que possamos ampliar o paralelismo em nível de threads e de
núcleos.
No paralelismo em nível de threads, o processador tem condições de escalonar
threads na ocorrência de conflitos no pipeline. Tratando-se de um escalonamento
em nível de hardware, torna-se muito mais eficiente, se compararmos com o
escalonamento realizado pelo sistema operacional (LEME, 2016).
Por sua vez, o paralelismo em nível de núcleos, incorpora a ideia das máquinas
multiprocessadores. Os vários processadores foram transformados em núcleos –
cada núcleo independente, com suas estruturas de controle e memória cache L1.
Não devemos deixar de destacar a volta da ênfase aos processadores vetoriais.
Uma arquitetura vetorial consiste em um modelo paralelo, dotado de pipeline, do
tipo SIMD
(Single Instruction, Multiple Data, em português, Instrução Única, Múltiplos Dados).
Neste modelo, vários dados são executados por uma única instrução. Como
exemplo, podemos falar das GPUs (Graphics Processing Unit, em português,
Unidade de Processamento Gráfico), no qual os dados a serem processados são
representados por vetores e as instruções são otimizadas para esse tipo de
manipulação.
Por fim, diversas são as pesquisas para explorar outras formas de paralelismo, não
se limitando às abstrações arquiteturais (OLIVEIRA; CAVALCANTE, 2010).
Podemos deixar, por exemplo, uma provocação para sua pesquisa e, por
consequência, para sua formação acadêmica, sugerindo um estudo sobre
paralelismo em nível de aplicações, por exemplo, o paralelismo em nível de dados
(DLP – Data Level Parallelism).

Síntese
Chegamos ao final de mais um capítulo. Esperamos que a sua trajetória tenha sido satisfatória e que o
conteúdo aqui abordado tenha ampliado seus horizontes e conhecimentos. Neste capítulo,
estudamos alguns aspectos físicos da memória interna, assim como pudemos abordar aspectos
inerentes aos módulos de E/S. Pudemos ver, também, aspectos relacionados à execução das
instruções em máquinas RISCs e CISCs e superescalares.

Neste capítulo, você teve a oportunidade de:


• reconhecer aspectos inerentes à memó ria interna, no quesito de sua
implementaçã o e funcionalidades;
• analisar e comparar as estruturas e formas de manipulaçã o dos mó dulos de E/S;
89

• discutir e identificar os modelos computacionais RISC e CISC, situando-os nos


atuais modelos de processadores;
• esboçar modelos baseados na superescalaridade e em algumas outras formas de
paralelismo. As abstraçõ es contraídas poderã o ser aplicadas em futuros projetos de
desenvolvimento de sistemas computacionais.

Projeto
UMA NOVA REALIDADE EM PROCESSAMENTO E
ARMAZENAMENTO DE DADOS

Segundo o trabalho de Orlando dos Santos Conceição Junior (2016, p.


14), “A Computação e a Informação Quântica podem ser entendidas
como, o estudo de tarefas que podem ser executadas valendo-se do
processamento de informações contidas em sistemas quânticos. De
forma mais direta, é uma jovem promessa da Física e é a responsável
por estudar métodos que possam caracterizar, armazenar, compactar
e usar informações contidas em sistemas tratados sob as leis da Física
Quântica”.

Esse tipo de arquitetura utiliza a mesma forma de organização


computacional proposta por von Neumann, mas tem uma limitação
para áreas importantes, como a Inteligência Artificial. O motivo é a
baixa potência e velocidade ofertada.

Sendo assim, é importante ter conhecimento adequado sobre o


hardware que será utilizado para manipular esse tipo de informação
tão específica e muito comum atualmente.
90

Vamos praticar
Com a importância do hardware para proporcionar alto desempenho em sistemas
computacionais, é importante que nesta atividade você seja capaz de retratar o sistema de
entrada e saída, tipos de memórias internas, a nova geração de processamento e
armazenamento quântico e a relação com paralelismo quântico.

O seu texto deverá conter uma lauda e deverá conter uma proposta de análise que discorra
sobre novas tecnologias de processamento, armazenamento e paralelismo quântico.

Exemplo de reportagens que tratam do assunto:

TARANTOLA, A. Drive quântico guarda dados por 100 vezes mais tempo e quebra recorde. Giz
Modo, São Paulo, 15 jan. 2015. Disponível em: <https://gizmodo.uol.com.br/drive-
quanticohoras>. Acesso em: 13 set. 2019.

TECMUNDO. É hora de descobrir os segredos da Computação Quântica. 28 ago. 2009.


Disponível em: <https://www.tecmundo.com.br/computacao-quantica/2666-e-hora-
dedescobrir-os-segredos-da-computacao-quantica.htm>. Acesso em: 13 set. 2019.

TECMUNDO. Experimente o “computador quântico em nuvem” da Google. 23 maio. 2014.


Disponível em: <https://www.tecmundo.com.br/computacao-quantica/55008-
experimentecomputador-quantico-nuvem-google.htm>. Acesso em: 13 set. 2019.

UNIVERSIDADE DE SÃO PAULO. Computador Quântico. Ciência Mão, São Paulo, s/d. Disponível
em: <https://www.ime.usp.br/~map/tcc/2018/WagnerJorcuvichV3.pdf>. Acesso em: 13 set.
2019.

Você também pode gostar