O que acontece entre apertar Enter e o programa rodar. Esta série abre a máquina
camada por camada: a álgebra booleana e a simplificação dos circuitos lógicos, a
hierarquia de memória e a cache, os componentes da CPU e o ciclo de instrução, o
pipeline e os barramentos, a representação de dados e de instruções, a tradução
de código-fonte em código de máquina — com uma parada no pipeline do CPython —, a
entrada e saída, e as arquiteturas paralelas modernas.
Os artigos são listados abaixo, na ordem em que foram escritos.
Você aperta Enter e o resultado aparece três décimos de segundo depois. Nesse intervalo, o processador buscou centenas de milhões de instruções na memória. Esta série de 13 artigos explica como: memória, cache, CPU, pipeline, representação de dados e execução de programas.
Se o acesso a um registrador durasse um segundo, o acesso à memória principal levaria quatro minutos e meio, e a um disco rígido, mais de um ano. Veremos a hierarquia de memória, células, endereços e barramentos, as fórmulas de dimensionamento e SRAM, DRAM, ROM e ECC.
Com 95% de acerto, a cache faz o processador enxergar uma memória de 4,95 ns onde a DRAM leva 80 ns. Veremos por que ela funciona (localidade), os mapeamentos direto, associativo e por conjuntos, os algoritmos de substituição e as políticas de escrita.
Um processador de 2 GHz pode executar mais instruções por segundo que um de 3 GHz. Para entender por quê, abrimos a CPU: UAL, unidade de controle, registradores, flags, decodificador e relógio, e os microeventos do ciclo de busca em notação formal.
Um processador hipotético de 12 bits, com 15 instruções, serve de modelo para acompanhar o ciclo de instrução completo. Executamos LDA e ADD registrador por registrador, codificamos instruções em hexadecimal e escrevemos programas em assembly com desvios e laços.
Uma linha de montagem não espera um carro ficar pronto para começar o próximo, e o pipeline faz o mesmo com as instruções. Veremos os estágios, os hazards que travam a linha, o cálculo do speedup, os barramentos que ligam CPU, memória e periféricos e a unidade de controle.
Maiúscula e minúscula diferem por um único bit na tabela ASCII, e não foi por acaso. Para o hardware tudo são bits, e o valor depende da convenção de leitura: ASCII, Unicode e UTF-8 para texto, complemento a dois para inteiros e IEEE 754 para números reais.
A mesma expressão custa 5 instruções com três operandos, 7 com dois e 11 com um acumulador. Veremos a ISA, o contrato entre hardware e software, os formatos de instrução, o R-type do RISC-V e os sete modos de endereçamento que dizem onde está cada operando.
Você escreve uma linha de código, e o processador só entende bits. Acompanhamos a tradução: montador em duas passagens, fases do compilador, ligação e carregamento. No caminho, o GCC reduz doze instruções a duas com -O2, e vemos onde ficam Python e Java entre compilar e interpretar.
Python não executa seu código linha a linha: antes, o CPython o compila para bytecode. Com os módulos tokenize, ast, compile e dis, acompanhamos uma expressão simples dos tokens à árvore sintática e ao bytecode, direto no interpretador.
Esperando um disco de 10 ms em espera ativa, uma CPU de 1 GHz desperdiça dez milhões de ciclos. Comparamos as três formas de tratar entrada e saída (polling, interrupções e DMA), calculamos o overhead de cada uma e vemos por que o polling voltou com os SSDs NVMe.
Com 10% de código serial, oito núcleos deixam o programa 4,7 vezes mais rápido, e nenhuma quantidade de núcleos passa de 10 vezes. Fechamos a série com RISC e CISC, métricas de desempenho, a taxonomia de Flynn, SMP, clusters, NUMA, multicore e a Lei de Amdahl.
Toda operação de um processador se descreve com três operações lógicas: AND, OR e NOT. Vamos das portas e tabelas verdade aos teoremas, às leis de De Morgan e à simplificação de expressões, com o meio-somador como primeiro circuito e exemplos em Python.
Como passar de uma tabela verdade para a expressão booleana mais enxuta? Mostramos três caminhos: as formas canônicas com mintermos e maxtermos, a simplificação algébrica e o mapa de Karnaugh, com exercícios resolvidos e conferência em Python com o SymPy.