Introduç o A Arquitetura de Computadores

Fazer download em txt, pdf ou txt
Fazer download em txt, pdf ou txt
Você está na página 1de 6

Introdução a arquitetura de computadores

Mensagem por cobreiro » Qui Jan 10, 2019 6:30 pm

Olá, nesse post vou explicar o básico sobre arquitetura de computadores, caso
queira aprofundar mais no assunto, recomendo que leia o livro:
http://producao.virtual.ufpb.br/books/e ... /livro.pdf.
Certo, inicialmente consideremos que você é um peão sertanejo e use um jegue como
meio de locomoção, um belo dia o seu jegue quebrou a pata mas você não entende
sobre a arquitetura dos jegues, então, sem compreender o ocorrido, tenta colocar o
animal pra funcionar no tapa até que o bicho morre e o Ibama vem atrás de você.
Caso você entendesse sobre a arquitetura dos jegues esse infortúnio não teria se
transformado em tragédia. O mesmo conhecimento poderia ser extremamente útil caso
você algum dia quisesse sabotar o jegue de outra pessoa, com ele você saberia que
quebrando a pata do outro animal ele não poderia andar. Na mesma linha de
raciocínio vamos para os computadores. Assim como os jegues precisam das 4 patas
para servirem de transporte pra você, os computadores precisam de 2 elementos
fundamentais: a memória e a Unidade Central de Processamento (CPU). A memória
inclui qualquer mecanismo de armazenamento de dados e a CPU é a responsável por
manipular esses dados. Para manipular um dado a CPU precisa, antes de tudo,
solicitar à memória tal dado, porém, nem tudo são flores. É preciso saber que
existe uma diferença considerável entre a velocidade de trabalho de uma CPU e de um
dispositivo de armazenamento. O problema disso é que a CPU passará longos períodos
em estado ocioso, perdendo muito tempo em processos que poderiam ser realizados num
piscar de olhos caso o dispositivo de armazenamento não fosse uma mula manca e,
como disse Clarisse Linspector: “Tempo é dinheiro”. Para abafar esse problema, os
engenheiros evoluem os dispositivos de armazenamento a cada ano, visando sempre
chegar o mais próximo possível de uma CPU. Acontece que o preço desses dispositivos
é proporcional ao seu desempenho e à quantidade de dados suportados, dessa forma é
inviável exagerar na tecnologia. Assim, foi adotado um esquema de hierarquia no que
diz respeito ao armazenamento de dados, ou seja, os dados mais importantes para a
CPU num determinado momento ficam armazenados nos dispositivos mais avançados e
consequentemente em menor quantidade. A estrutura dessa hierarquia seria mais ou
menos essa:

- HD, cartão SSD, pendrives: Essa é a vala da hierarquia, porém, apesar disso, os
dispositivos aqui presentes possuem uma capacidade única em relação aos outros
dispositivos de armazenamento: podem ter os dados reescritos e, ao mesmo tempo, não
precisam de energia para mantê-los salvos. Além disso, são dispositivos com um
baixo custo por bit. A desvantagem é que, são extremamente lentos em relação à CPU.
O HD é o mais lento por se tratar de um dispositivo mecânico, ou seja, toda vez que
um dado dele for requisitado, ele deverá mover o disco, ajustar o braço do leitor e
só então fazer a coleta de dados.
- Memória principal, composta pelo tipo RAM dinâmica ou DRAM: Mais cara que o tipo
anterior, funciona na base de transistores e capacitores. Os capacitores são
componentes eletrônicos capazes de armazenar uma carga elétrica por um certo
período de tempo, eles ficam carregados para representar o bit 1 e descarregados
para o bit 0. O transistor funcionará como um portão, ou seja, ele definirá se o
capacitor irá ou não receber a carga para armazenar, dependendo do bit a ser
representado. Cada bit que a memória armazena precisa de 1 capacitor e um
transistor. A vantagem desse tipo de memória é que ela ocupa um espaço pequeno
(cada par transistor/capacitor ocupa um espaço microscópico) e é relativamente
barata se comparada às memórias superiores hierarquicamente. A desvantagem é que,
com apenas um par transistor/capacitor, ela precisará de ser recarregada
constantemente e, durante o período de recarga, ela fica inacessível pela CPU. Isso
limita bastante o seu desempenho e a torna não tão ideal para manter um contato
mais íntimo com a CPU.
- Memória cache, composta pelo tipo RAM estática ou SRAM: Bem mais cara que a
anterior e ocupa um espaço maior, limitando bastante seu uso. Diferente da DRAM,
essa utiliza um circuito conhecido como flip-flop composto por entre 4 e 6
transistores e um capacitor, não necessita de um período dedicado para a recarga,
portanto, é bem mais rápida que a dinâmica. Além disso, para reduzir a latência
ainda mais, ela é localizada muito próxima da CPU, as vezes até dentro da mesma.
- Registradores, também utilizam o mesmo sistema flip-flop da memória cache, a
diferença é que possuem muito mais tecnologia envolvida, visando aumentar ao
extremo a sua velocidade de atuação. Localizam-se dentro da CPU e, portanto, mantém
contato direto com ela ficando no topo da pirâmide. Cada máquina possui suporte a
apenas alguns KB de dados em registradores devido ao alto custo.

Além dos tipos citados acima, existe a chamada Memória ROM (Read Only Memory, em
brazuca, Memória Somente de Leitura). Os dispositivos desse tipo, como o nome
sugere, não foram feitos para serem atualizados o tempo todo (existem vários tipos
de ROM variando no processo de escrita e reescrita, alguns mais porretas outros
mais de boas), por isso, são usados principalmente para o armazenamento dos
firmwares da máquina, ou seja, os programas responsáveis pelo funcionamento básico
da máquina que não devem ficar sujeitos às ações de um fimosudo qualquer. Um
exemplo clássico de firmware é a BIOS (Basic Input/Output System, Sistema Básico de
Entrada e Saída), o programa responsável pelo processo de inicialização da máquina
(hoje, vem sendo substituído pelo padrão EFI, mesmo assim, foquemos no exemplo), é
ele quem carrega o sistema operacional (que se encontrará no HD, por exemplo).
Devido ao fato de ser um programa que interage diretamente com o hardware, não
faria sentido armazená-lo num dispositivo tão instável como o HD, porque se o
dispositivo queimasse ou danificasse a parte que continha o programa, toda a
máquina seria prejudicada.

Quando eu escrevi esse artigo eu esqueci de definir 2 conceitos importantes, o de


Memória interna e externa. Bom, é chamado de memória interna, o conjunto de todos
os dispositivos de armazenamento que atuam de forma mais direta com o processador.
Nessa classificação estarão: a memória principal, a memória cache, os registradores
e a memória ROM. Já a externa ou memória auxiliar inclui aqueles dispositivos mais
lentos incapazes de aguentar o tranco perto do processador que, em compensação,
possuem maior capacidade de armazenamento somada com o poder de guardar os dados
mesmo quando desligados.

Agora que eu passei uma visão geral sobre cada tipo de memória, vamos entender como
funciona essa hierarquia na prática. A frequência de trabalho de um processador é
chamada de clock, consiste na quantidade de vezes que o processador atualiza seu
estado em um intervalo de tempo, atualmente, os processadores trabalham num clock
de pelo menos 2 Ghz (2 * 10^9 ciclos por segundo) variando de modelo pra modelo.
Então, podemos deduzir que o ideal é que a memória trabalhe no mesmo clock do
processador, porém, como eu disse lá em cima, nem tudo são flores, e sim um monte
de bosta amassada com uvas-passas e palmito, mesmo assim, é possível reduzir a
latência entre os 2, quanto mais alta a hierarquia da memória, maior o clock de
operação da mesma. Os registradores são usados para guardar dados apenas do
processo que está sendo executado, dessa forma, existem 2 tipos de registradores,
os de propósito geral e os de propósito específico. Os do primeiro tipo são usados
para guardar valores de variáveis, resultados de uma determinada operação, dados
buscados na memória para serem usados e qualquer tipo de dado que o programa possa
precisar. Já os de propósito específico, armazenam dados essenciais para a execução
de qualquer programa, por exemplo, o registrador PC (Contador de Programa) é usado
para guardar o endereço na memória (geralmente será a cache) da instrução atual
sendo incrementado ao final dela. A memória cache deve armazenar os dados mais
prováveis de serem requisitados pela CPU, para isso existem altas bruxarias a fim
de conseguir acertar os pedidos da CPU. Ela é dividida em 3 tipos: cache L1 (Level
1 ou nível 1) de instruções e dados, cache L2 de dados e cache L1 de dados
(escrita). O cache L2 está entre a memória principal e o cache L1, nele é usada uma
tecnologia inferior ao cache L1, porém superior à memória principal, seu uso é de
propósitos gerais. O cache L1 de instruções e dados possui uma divisão entre
instruções e dados gerais (como a porra do nome já diz) para que a CPU possua um
barramento (o canal de acesso) dedicado para ambos propósitos a fim de conseguir
buscar a próxima instrução ao mesmo tempo que lê os dados solicitados pela
instrução anterior antes mesmo dela terminar (futuramente explicarei sobre isso,
chama-se pipeline ou execução paralela em nível de instruções) já que um único
barramento não poderia ser usado simultaneamente. O cache L1 de dados para escrita
será usado para armazenar a saída da CPU, isso porque, assim como a velocidade de
leitura da memória SRAM é diferenciada, a de escrita também é, então, existe esse
cache que servirá somente para escrita até que os dados sejam levados à memória
principal por outra chipset de maneira a não atrapalhar o desempenho da CPU. A
memória principal é usada como depósito geral e existe um chipset específico que se
encarregará de passar os dados da memória principal para a memória cache. No poço
da hierarquia temos os dispositivos rígidos como o HD e o cartão SSD, apesar de
extremamente lentos, esses dispositivos são usados como complemento da memória RAM,
ou seja, usados para armazenar os dados no mesmo formato que são armazenados na
RAM. A chamada memória SWAP ou memória virtual, consiste em um espaço dedicado no
dispositivo rígido para armazenar dados de baixa hierarquia (que foram usados com
frequência a um tempo mas no momento não estão sendo) que podem vir a ser
requisitados futuramente. O uso do SWAP pode ser facilmente configurado para manter
a maior quantidade de dados possíveis na RAM (não me lembro como que faz isso no
Linux e muito menos no Windows, se lembrarem comentem nessa bosta aí). Usar o SWAP
em demasia pode prejudicar o desempenho da máquina, não usá-lo também pode trazer o
mesmo efeito.

Vou cortar o rabo (Sim, meninas, sinto muito acabar com suas ilusões, homens também
cagam) e fazer um café, logo continuo essa porra.
AFK

Desculpem a demora, aqui estamos novamente. Esse post vai ficar grande pra cacete,
mesmo assim, explicarei o funcionamento básico de uma CPU.

Primeiramente preciso dizer que, para fins didáticos, falaremos de um computador de


apenas um núcleo de processamento, ou seja, um único processador. Vamos ao que
interessa. Uma CPU consegue executar apenas instruções pré-configuradas, por
exemplo: ler tal endereço de memória, escrever em tal endereço, executar tal
operação matemática (podem ser compostas por outras instruções, por exemplo: a
multiplicação pode ser a repetição de uma instrução de soma) ou lógica, dessa
forma, é preciso que exista uma parte da CPU responsável por traduzir um comando de
um binário (programas executáveis em linguagem de máquina) em instruções que podem
ser compreendidas pela ULA (Unidade Lógica e Aritmética) ou qualquer unidade de
tratamento de dados que eu citarei abaixo. Vou explicar melhor, imagine um programa
já compilado, ou seja, um binário gerado a partir de um código fonte, esse programa
na maioria das vezes pode ser usado em diversos computadores da mesma arquitetura
(64 ou 32 bits), porém, existem vários modelos de processadores de marcas distintas
e mesma arquitetura com métodos de execução diferentes, então como eles conseguem
executar o mesmo binário? Bom, a CPU é dividida em 2 partes principais: a Unidade
de Controle (UC ou CU, hihihihi) e a Unidade de Ciclo de Dados (UCD), na UCD
encontra-se a ULA (Unidade Lógica e Aritmética, citada lá em cima e as outras
unidades de tratamento de dados). A UC é responsável por decodificar uma instrução
e passá-la para a UCD, o processo de decodificação consiste basicamente em pegar
uma instrução de um binário genérico e transformar numa instrução que a UCD consiga
compreender. Voltemos ao exemplo do jegue: na cabeça do jegue existe uma UCD e uma
UC (perceba que eu usei UC porque o jegue tem um CU também, hihihihihi), Digamos
agora que tem um mecanismo perto do CU do jegue que possui um botão e, quando uma
bosta pressiona esse botão, é enviado uma mensagem pra UC dizendo “tem uma parada
me cutucando aqui”, caso essa mensagem seja enviada direto pra UCD, ela não será
capaz de compreender, então, a UC envia um comando traduzido pra UCD dizendo “Caga
ai, mano”, então o jegue caga. No computador é exatamente a mesmíssima coisa, a UC
recebe uma instrução genérica que seria usada em qualquer máquina com a mesma
arquitetura e traduz para a UCD num comando específico daquela máquina. Todo o
procedimento, desde a busca de uma instrução na memória até a finalização da
execução dele, é dividido em passos. Primeiro, a UCD irá ler um registrador
conhecido como PC (o mesmo do exemplo do início do texto, contador de programa),
esse registrador indica o endereço (posição na memória, perceba que me refiro a
memória no geral, pode ser tanto a cache quanto a principal) da instrução a ser
executada, após isso, o conteúdo dele é passado para o controlador de memória por
meio de um barramento dedicado para endereços entre a memória e a CPU, a placa
controladora da memória então retornará a instrução por meio de um barramento
dedicado de dados que será armazenada no registrador IR (Registrador de Instrução),
após isso, essa instrução é decodificada e passada para a UCD especificando qual
será a unidade que deverá executar a instrução, pode ser a ULA (trata operações
lógicas como os condicionais, e operações aritméticas com inteiros no geral), a UPF
(Unidade de Pontos Flutuantes, responsável pelo tratamento de pontos flutuantes, ou
seja, números reais) e outros tipos de unidades, cada um com uma funcionalidade
específica. Na unidade correta, a instrução pode solicitar a busca de um dado num
determinado endereço da memória, para isso, esse endereço é passado para o
registrador MAR (Registrador de Endereço de Memória, usado somente para dados) que
então será passado para a placa controladora da memória por meio de um outro
barramento dedicado de endereços, o retorno será feito por meio de outro barramento
dedicado de dados e será armazenado no registrador MBR (Registrador de Buffer de
Memória). Já no registrador, o dado pode ser usado pela UCD. Ao final da execução
de uma instrução, o PC é incrementado em uma unidade, ou seja, apontará para o
endereço posterior ao atual e todo o processo é repetido, dessa forma, as
instruções são executadas de maneira sequencial. Vamos pegar um exemplo: queremos
executar a operação M + N e salvar num endereço X, sendo M um número inteiro
localizado no endereço &M e N um número inteiro passado pelo usuário através do
teclado:

Código: Selecionar todos

//fim da instrução anterior


- PC=PC+1 ##PC recebe o próximo endereço
- Solicitação da instrução do endereço armazenado no registrador PC por meio do
barramento de endereços para placa controladora de memória
- Placa controladora de memória envia por meio do barramento de dados o valor de PC
que é salvo em IR
- UC envia valor de IR para a ULA (por ser uma operação com números inteiros)
localizada na UCD
- UCD solicita à placa de memória o valor contido em &M por meio do barramento de
endereços
- Placa controladora de memória responde pelo barramento de dados e o valor contido
em &M é salvo em R1, um registrador de propósitos gerais (como eu expliquei no
início do post)
- UCD coloca o processo em modo de espera até que o usuário digite o valor de N
- Valor digitado pelo usuário é armazenado na memória do teclado (sim, cada
dispositivo possui uma memória dedicada, pois, dessa forma o processador pode ficar
executando outra coisa enquanto espera o usuário digitar o valor, falarei disso
mais a frente) e passado para o registrador MBR via barramento de dados.
- ULA executa operação R1 + MBR e salva em R2
- UCD solicita a placa de memória para que escreva o valor contido em R2 no
endereço X na memória cache L1 que futuramente, para não atrapalhar a CPU, será
copiado para a memória principal.
- PC recebe PC+1

Como podem ver, enquanto a CPU está no meio da execução de uma instrução, ela está
com algumas partes ociosas, então, para aumentar a eficiência, é usada uma técnica
conhecida como pipeline, ou execução em paralelo em nível de instrução. Essa
técnica consiste em basicamente executar o máximo de passos possíveis, para isso,
toda instrução é dividida em etapas. Para facilitar, vamos considerar que são
apenas 5 etapas:

1- Carregar instrução
2- Carregar operandos
3- Executar instrução
4- Salvar na memória
5- Salvar em um registrador, se necessário

Sim, eu menti pra você, no exemplo de cima eu considerei que o dado era antes
jogado num registrador e só depois passado pra memória, mas foi só para facilitar a
explicação. Outra mentira minha foi dizer que o PC só é incrementado no final do
último passo mas, para que o pipeline funcione, ele deve ser incrementado ao final
da etapa 1, vou explicar o por quê.

Dessa forma, quando uma instrução de endereço X sair da etapa 1 e ir para a 2, a


instrução de endereço X+1 já vai para a etapa 1. Quando a instrução de endereço X
estiver na etapa 5, todas as outras etapas já estarão preenchidas, dessa forma, a
CPU não vai ter tempo pra coçar o saco e o desempenho dela vai aumentar de acordo
com a quantidade de etapas que suportar, só para se ter uma ideia, os processadores
atuais possuem mais de 20 etapas.

Antes de continuar vou fazer mais café, estou tremendo para caraleo.
Voltei.

Acontece que, como eu já disse 2 vezes, nem tudo são flores. O que acontece quando
a CPU está diante de um condicional? Por exemplo, “Se o valor retornado pela
instrução de endereço X+1 for igual a 0 execute a instrução de endereço X+2, senão
execute a instrução de endereço X+6”. Agora a vaca foi pro brejo, porque, nesse
caso, o programa não executará instruções numa sequência lógica, então é impossível
saber qual será a próxima instrução antes de finalizar a primeira. Esse mesmo
problema ocorre com os loops (que também são condicionais) e é um pé no saco da
CPU. Para tentar contornar isso, as CPUs atuais possuem vários registradores de
cada tipo, dessa forma, é possível carregar a instrução a ser chamada em cada
possibilidade. Obviamente existe um limite para isso, não vai esperando que aquele
seu condicional maroto de 60 possibilidades vai ser executado tranquilamente. De
qualquer forma, esses desvios são prejudiciais para o desempenho da CPU, pois
ocuparão algumas das etapas inutilmente. Outra solução além do paralelismo em nível
de instruções é o paralelismo em nível de hardware que consiste em, basicamente,
usar mais de um núcleo de processamento. Dessa forma, mais instruções podem ser
executadas nos mesmos instantes de clock. Não sei se ficou claro, mas um clock não
é necessariamente o período de execução de uma instrução, pois existem algumas
instruções mais custosas que outras e demandarão mais ciclos. Sabendo isso, é
possível deduzir que o clock do processador não pode ser usado como parâmetro de
comparação do desempenho de uma CPU, pois, uma CPU de clock mais baixo (menor
frequência) pode executar mais instruções por ciclo do que um outro modelo com
clock maior. Os fatores mais influentes no desempenho de uma CPU são: a quantidade
de registradores e organização dos mesmos, tempo de execução de uma tarefa (variará
de acordo com a tarefa, por exemplo, trabalhar com pontos flutuantes é mais foda do
que mexer com inteiros), quantidade de núcleos e o desempenho da memória (inclui
quantidade de cache, capacidade do chipset responsável em prever quais dados serão
solicitados e a latência entre ela e a CPU).

Outro mecanismo importantíssimo de uma CPU é o de interrupção. Imagine a seguinte


situação: a CPU está executando as instruções sequenciais normalmente, ou seja, uma
instrução é executada, a CPU chama a próxima e assim vai até que não haja mais nada
a ser processado. O que aconteceria caso algum dispositivo de entrada resolvesse
atuar, como, por exemplo, a placa de rede receber algum pacote ou o mouse ser
movimentado? Bom, se CPU estivesse executando um ciclo fechado, ou seja, uma
sequência indeterminada de instruções, nada aconteceria a não ser acrescentar o
evento ocorrido no final da fila. Acontece que os eventos causados por dispositivos
de entrada devem possuir prioridade máxima, ou seja, se por ventura uma instrução
qualquer está sendo executada e surgir um evento decorrente de uma tecla apertada,
ele deve furar a fila da sequência de execução, essa furada de fila é chamada de
interrupção. Toda interrupção deve ser solicitada para um chip chamado de
gerenciador de interrupções, esse gerenciador enviará um sinal à UC via barramento
de controle (um barramento específico para operar diretamente a CPU) e armazenará o
código da interrupção. Ao final da execução de cada instrução, a UC verifica se
existe uma interrupção pendente, caso não, ela continuará executado as instruções
da fila normalmente, do contrário, ela salvará o estado dos registradores e passará
o endereço de um programa especial para o PC, o chamado Tratador de Interrupção.
Cada tipo de interrupção possui um tratador específico que será definido de acordo
com o código passado pelo gerenciador de interrupção. Esse programa executará a
instrução relativa ao evento ocorrido e só então a CPU recuperará o seu estado
anterior. Outro exemplo de interrupção é quando o programa tenta executar uma
operação ilegal, como, por exemplo, acessar a memória de outro processo. Caso isso
ocorra, será gerada uma interrupção de erro que vai brecar o processo relativo a
tal instrução e retornar uma mensagem para o usuário.

Espero que todos tenham compreendido meus exemplos, sei que as vezes são um pouco
absurdos porém fizeram muito sentido pra mim no meu estado atual. Só agora que
percebi que escrevi 5 páginas, e não vou ler esta bosta antes de postar, já são
quase 7 horas e a cafeína está perdendo o efeito, sinto muito por isso. Se você leu
isso até aqui e achou algum erro gramatical, culpe o corretor do Open Office e o
café de má qualidade.

Um abraço do cobreiro.

Referências além do livro recomendado na ementa:


http://www.davanso.com/apostila/aula04_hardware.htm

Você também pode gostar