Você, programador, sabe como um computador funciona?
Dizer que é uma máquina que sabe interpretar números binários está até que relativamente correto, porém você sabe elaborar mais um pouco sobre isto? Tudo bem não saber a resposta pra esta pergunta, mesmo que num alto nível, afinal, no nosso dia a dia como desenvolvedores estamos trabalhando em uma camada muito acima, na hierarquia do computador, ou seja, extremamente distantes do “metal”.
Eu mesmo tinha uma noção, por ter feito faculdade de engenharia elétrica com ênfase em computação, porém, só fui me aprofundar no tópico mais recentemente, quando me interessei em aprender mais sobre emuladores.
Um último disclaimer é que, não se sinta pressionado em saber essa resposta também! Afinal, posso afirmar com certeza que você pode ser um ótimo desenvolvedor sem fazer o mínimo de noção de como uma computador está organizado, tendo uma noção de conceitos mais alto nível como memória, CPU, threads, I/O e etc. Nosso papel como desenvolvedores é o de nos especializarmos em algoritmos, concorrência e paralelismo e otimização do uso de I/O, podendo abstrair hoje 100% da parte do “metal”, principalmente na era da cloud.
Abstrações e magias que conseguimos com software
De uma perspectiva mais simplista, podemos dividir a organização de um computador da seguinte forma:
Sendo a camada mais externa, o software que nós programadores escrevemos, usando linguagens de programação como C, C++, Java, Ruby, Go, etc.
A camada intermediária seria a interface entre nosso software com o hardware de fato, sendo dois grandes exemplos de software de interface os compiladores e os sistemas operacionais.
O papel do sistema operacional normalmente é o de prover diversas APIs ao hardware assim como mandar funções de supervisionamento.
Alguns exemplos de funções importantes do OS (operating system, ou sistema operacional):
- Lidar com I/O
- Alocação de memória e armazenamento (disco)
- Prover uma interface segura para que diferentes aplicações possam utilizar os recursos do computador de maneira simultânea e harmoniosa
Compiladores executam uma tarefa vital também para o funcionamento dos programas, eles “traduzem” programas escritos em linguagens mais alto nível (como C ou Java) em instruções que o hardware consegue executar, chamadas de machine language (ou linguagem de máquina). Alguns compiladores conseguem executar uma tradução direta, outros utilizam um passo intermediário, onde transformam o código alto nível em um de mais baixo nível chamado de assembly, que nada mais é do que uma linguagem que abstrai um pouco a linguagem de máquina (bits) em instruções mais fáceis de um humano entender, porém estando bem mais próximo do jeito que computadores de fato funcionam. O software que consegue converter assembly em linguagem de máquina é normalmente chamado de assembler.
Olhando embaixo do capô
Após analisar um pouquinho como as camadas de software interagem e compunham nossos programas, vamos abaixar um degrau e olhar como a parte de hardware funciona.
Existem 5 principais categorias de componentes de um computador, qualquer componente, seja ele antigo ou moderno, pode ser categorizado sob essas cinco categorias. Elas são input (entrada), output (saída), memória, datapath (caminho de dados) e controle, sendo datapath e controle normalmente agrupados como processadores.
I / O
Dispositivos de I/O são os dispositivos que geram dados de entrada e saída no computador, normalmente são os que estamos mais familiarizados, exemplos de dispositivos de I/O são monitores, teclados, mouses, placas de rede, bluetooth, câmeras, microfones, etc.
Não entraremos tanto em detalhes pois cada dispositivo diferente de I/O tem seu propósito específico, além disso, já estamos mais familiarizados com seus funcionamentos.
Memória
Memória é basicamente o componente responsável por guardar instruções de programas e dados do computador.
Existem algumas categorias de memórias, sendo a mais comumente conhecida a DRAM (dynamic random access memory). RAM (random access memory) é um termo utilizado para denominar unidades de armazenamento que levam o mesmo tempo para acessar qualquer parte desta unidade, ou seja, não importa em qual parte o dado se encontra, fisicamente, ele pode ser acessado no mesmo intervalo de tempo.
Dentro do processador encontramos um outro tipo de memória chamada de Cache, uma memória extremamente rápida, que é utilizada como um buffer da DRAM (um buffer nada mais é do que um espaço onde dados que são mais frequentemente utilizados são guardados, sendo este um local de maior performance, economizado outros recursos e tornando o computador mais eficiente como um todo). A tecnologia utilizada para construir um Cache do processador é chamada de SRAM (static random access memory), uma tecnologia muito mais rápida do que a DRAM, porém mais cara.
Tanto a DRAM quanto a SRAM são tecnologias de memória voláteis, ou seja, assim que a energia do computador é cortada elas são completamente apagadas. Tendo esta característica em mente, surgiu a necessidade de termos um espaço diferente no computador para armazenarmos dados persistentes, assim surgiram os discos magnéticos, uma tecnologia de armazenamento de longo prazo, onde os dados ficam gravados mesmo quando não há energia no computador. Posteriormente, principalmente com o advento de dispositivos mobiles, um segundo tipo de tecnologia de armazenamento de local prazo surgiu como alternativa, o flash memory, sendo bem utilizado por conta de seu tamanho físico e custo por bits.
Na hierarquia de memória, chamamos DRAM / SRAM de memória primária, enquanto flash memory e discos magnéticos são categorizados como memória secundária.
Processador
O processador ou CPU é um componente complexo dos computadores, formado por diversas sub-máquinas, ele é responsável por buscar instruções da memória, decodificá-las, executar as operações (contas aritméticas, acesso a memória ou controlar outras parts do sistema) e escrever os resultados de volta, seja na memória ou em seus registradores. Todos essas passos são executados em um loop ininterrupto.
Alguns componentes notórios da CPU são seus registradores, a ALU (arithmetic logic unit) e suas unidades de controle.
Registradores são unidades de memória do processador, totalmente separadas da RAM, onde são guardadas dados intermediários, frutos de algum processo de cálculo, registradores de inputs, que guardam dados da RAM e de outputs, que enviam resultados de volta pra RAM (normalmente como buffers).
ALU é a unidade lógica aritmética, nada mais é do que um conjunto de maquinas simples que tem o papel de executar operações aritméticas, cada uma especializada em um tipo de operação.
A unidade de controle é responsável por ler instruções de um programa da RAM, decodificá-las e passa-las para a ALU ou pra outro lugar para serem executadas (como gravar algo em disco ou executar algo em I / O). Após este passo, ela atualiza o ponteiro do programa (PC, program counter), que mantém guardado a informação da localização da próxima instrução a ser executada. As instruções são lidas sequencialmente ou executando pulos (ou seja, indo para um lugar não sequencial baseado em alguma instrução prévia).
A interface entre hardware e o software
Um dos princípios fundamentais da arquitetura de computadores é que abstrações simplificam o design. Isso significa que ao utilizar abstrações, programadores e arquitetos podem se comunicar de forma mais eficaz. Um dos avanços significativos na área da computação foi ocultar os detalhes de implementação do hardware, expondo apenas um modelo simples e padronizado para que os programadores pudessem escrever seus programas.
Uma das mais importantes abstrações é a interface entre hardware e software, que chamamos de instruction set architecture (ISA). A ISA é formada por uma série de instruções que o computador é capaz de executar, como operações aritméticas, I / O e etc.
Tipicamente, temos o sistema operacional que encapsula detalhes de como fazer I / O, alocar memória e outras funções mais baixo nível, para que programadores não tenham que se preocupar com isto. A combinação de instruções básicas e a API fornecida pelo sistema operacional é chamada de application binary interface.
Qual a relação entre ISA e assembly?
A ISA caracteriza o que um hardware pode fazer, ou seja, inclui todas as instruções que uma CPU pode executar, endereço de seus registradores, o modelo de memória utilizado, como instruções são decodificadas, etc. A linguagem assembly é uma linguagem de programação que corresponde muito proximamente as instruções da ISA (Lembrando que as instruções da ISA normalmente são codificadas como um binário que representa determinada instrução específica).
A relação entre a ISA e o assembly é que o assembly proporciona uma representação passível de compreensão por humanos da ISA de determinado hardware.
Conclusão
Em resumo, podemos dizer que a arquitetura de computadores é um campo fascinante que abrange desde os conceitos mais abstratos, como a forma como os programas são escritos e interpretados pelos computadores, até os detalhes mais concretos, como o funcionamento interno dos componentes de hardware. Embora muitos programadores possam trabalhar sem a necessidade de entender profundamente esses detalhes, ter uma compreensão básica de como um computador funciona pode ser extremamente útil para compreender melhor o funcionamento dos programas que escrevemos e para tomar decisões de design mais informadas.
Referências
Imagens tiradas do livro Computer Organization and Design
Top comments (1)
Excelente artigo!!