College Online
0%

Barramentos e E/S

Módulo 5 · Aula 3 ~18 min de leitura Nível: Intermediário

Vídeo da aula estará disponível em breve

O que são Barramentos

Um barramento (bus) é um conjunto de fios compartilhados que conecta componentes do computador — processador, memória e dispositivos de E/S. É a infraestrutura de comunicação que permite que dados, endereços e sinais de controle fluam entre os componentes.

Diagrama — Tipos de Barramento
Três tipos de linhas em um barramento:

┌──────────────────────────────────────────────────────────────┐
│ BARRAMENTO DE DADOS (bidirecional)                           │
│ Transporta os dados propriamente ditos.                      │
│ Largura: 32, 64 ou 128 bits (determina a "palavra" do bus). │
├──────────────────────────────────────────────────────────────┤
│ BARRAMENTO DE ENDEREÇO (unidirecional: CPU → memória/IO)     │
│ Especifica o endereço de memória ou porta de I/O.            │
│ Largura: 32 ou 64 bits (determina espaço endereçável).       │
├──────────────────────────────────────────────────────────────┤
│ BARRAMENTO DE CONTROLE (bidirecional)                        │
│ Sinais de coordenação: Read, Write, Interrupt, Bus Request,  │
│ Bus Grant, Clock, Reset.                                     │
└──────────────────────────────────────────────────────────────┘

Visão geral da arquitetura de barramento:

                    ┌───────┐
                    │  CPU  │
                    └───┬───┘
                        │
          ══════════════╪═══════════════  System Bus (FSB/QPI/UPI)
                        │
                   ┌────┴────┐
                   │Northbridge│ (ou integrado no CPU moderno)
                   │(MCH/IMC) │
                   └────┬────┘
                  ╱     │      ╲
            ┌────┘    ──┴──     └────┐
            │       │ RAM │          │
         ┌──┴──┐    └─────┘     ┌───┴───┐
         │ GPU │                │Southbridge│
         │(PCIe)│               │ (PCH/ICH) │
         └─────┘                └───┬───────┘
                              ╱     │     ╲
                         USB   SATA    Audio
                         SSD   HDD    Ethernet

Comunicação Síncrona vs Assíncrona

Síncrono vs Assíncrono
BARRAMENTO SÍNCRONO:
  Todas as operações sincronizadas por um clock global.
  Todos os dispositivos operam na mesma frequência.

  Clock: ──┐  ┌──┐  ┌──┐  ┌──┐  ┌──┐  ┌──
            └──┘  └──┘  └──┘  └──┘  └──┘
  Addr:  ───[ENDEREÇO]──────────────────────
  Data:  ────────────────[DADOS]────────────
  R/W:   ───[READ]──────────────────────────

  + Simples de implementar (clock dita tudo)
  + Rápido (sem overhead de handshake)
  - Limitado pela velocidade do dispositivo mais lento
  - Clock skew em barramentos longos
  - Difícil conectar dispositivos de velocidades diferentes

  Exemplo: barramento de memória (DDR4/DDR5)

BARRAMENTO ASSÍNCRONO:
  Sem clock global. Usa protocolo de handshake.

  Req:   ──┐          ┌────────
            └──────────┘
  Ack:   ────────┐          ┌──
                  └──────────┘
  Data:  ───────[DADOS]────────

  Protocolo:
    1. Mestre coloca dados e ativa Req
    2. Escravo lê dados e ativa Ack
    3. Mestre vê Ack, desativa Req
    4. Escravo vê Req desativado, desativa Ack

  + Dispositivos de velocidades diferentes podem coexistir
  + Sem clock skew (não depende de clock global)
  - Overhead do handshake (mais lento por transação)
  - Mais complexo de implementar

  Exemplo: USB (usa pacotes, não clock compartilhado)

Mecanismos de E/S: Polling, Interrupções e DMA

Como o processador se comunica com dispositivos de E/S? Existem três mecanismos fundamentais, cada um com trade-offs diferentes:

Mecanismo 1 — Polling (Busy Waiting)
# Pseudocódigo: lendo um caractere do teclado via polling

loop:
    status = ler_porta(KEYBOARD_STATUS)    # lê registrador de status
    if (status AND READY_BIT) == 0:        # dado pronto?
        goto loop                          # não → tenta de novo
    dado = ler_porta(KEYBOARD_DATA)        # sim → lê o dado
    processar(dado)

Problema:
  CPU fica 100% ocupada verificando o status em loop.
  Se o teclado produz 10 caracteres/segundo e a CPU roda
  a 1 GHz: a CPU verifica ~100 milhões de vezes por caractere.
  99.999999% dos ciclos são DESPERDIÇADOS.

Quando usar:
  - Dispositivos muito rápidos (latência < custo de interrupção)
  - Sistemas embarcados simples (sem SO)
  - Quando o dado está quase sempre pronto (spin lock)
Mecanismo 2 — Interrupções (Interrupt-Driven I/O)
# Fluxo de interrupção:

1. CPU envia comando ao dispositivo ("leia um setor")
2. CPU continua executando outro código normalmente
3. Quando o dispositivo termina:
   a. Dispositivo ativa linha de INTERRUPÇÃO (IRQ)
   b. CPU termina instrução atual
   c. CPU salva estado (PC, registradores) na pilha
   d. CPU consulta vetor de interrupções → endereço do handler
   e. CPU executa o interrupt handler (ISR)
   f. Handler lê dado do dispositivo, processa
   g. Handler restaura estado e retorna (IRET/ERET)
4. CPU continua de onde parou

Vetor de interrupções (x86):
  IRQ  Dispositivo
  ───  ────────────
   0   Timer (PIT/HPET)
   1   Teclado
   3   COM2 (serial)
   4   COM1 (serial)
   6   Floppy disk
   8   RTC (relógio)
  14   IDE primário (disco)
  15   IDE secundário

Vantagem: CPU não desperdiça ciclos esperando.
Custo: overhead de salvar/restaurar estado (~100-1000 ciclos)
       → ruim para transferências de muitos dados pequenos.
Mecanismo 3 — DMA (Direct Memory Access)
# DMA: dispositivo transfere dados diretamente para a memória,
# sem passar pela CPU.

Sem DMA (programmed I/O):
  CPU lê palavra do dispositivo → escreve na memória → repete
  Para transferir 1 MB em palavras de 4 bytes: 262.144 iterações
  CPU 100% ocupada durante toda a transferência.

Com DMA:
  1. CPU programa o controlador DMA:
     - Endereço de memória de destino
     - Endereço do dispositivo (porta I/O)
     - Número de bytes a transferir
     - Direção (memória→dispositivo ou dispositivo→memória)

  2. DMA assume o barramento e transfere dados diretamente:
     Dispositivo ←→ DMA Controller ←→ Memória
     (CPU não participa, pode executar outro código)

  3. Quando transferência completa:
     DMA gera INTERRUPÇÃO para avisar a CPU.

  CPU                    DMA Controller
  ────                   ──────────────
  Programa DMA ────────► [addr][count][dir]
  Continua trabalhando   Transfere dados...
  ...                    ...
  ...                    ...
  Recebe interrupção ◄── Transferência completa!
  Processa resultado

Vantagem: CPU livre durante transferência de grandes volumes.
Usado em: disco (SATA/NVMe), rede, GPU, som.

Trade-off: DMA e CPU competem pelo barramento de memória.
"Cycle stealing": DMA usa o barramento quando CPU não está usando.
"Burst mode": DMA toma o barramento por vários ciclos consecutivos.
i
Na prática, os três coexistem Processadores modernos usam os três mecanismos: polling para dispositivos ultra-rápidos (como verificar se a cache de rede tem pacotes), interrupções para eventos assíncronos (teclado, timer), e DMA para transferências volumosas (disco, rede, GPU). O driver do dispositivo escolhe o mecanismo apropriado.

Memory-Mapped I/O vs Port-Mapped I/O

Como o processador endereça dispositivos de E/S? Existem duas abordagens:

Dois Modelos de Endereçamento de I/O
MEMORY-MAPPED I/O:
  Dispositivos são mapeados no espaço de endereçamento da memória.
  Ler/escrever em certos endereços acessa registradores do dispositivo.

  Espaço de endereçamento:
  0x00000000 ┌──────────────────┐
             │    RAM (3 GB)     │
  0xC0000000 ├──────────────────┤
             │ GPU framebuffer   │ ← escrever aqui = pixels na tela
  0xE0000000 ├──────────────────┤
             │ Registradores de  │
             │ dispositivos I/O  │ ← ler/escrever = controlar hardware
  0xFFFFFFFF └──────────────────┘

  # Pseudocódigo — acender LED via memory-mapped I/O
  GPIO_BASE = 0xE0020000          # endereço do controlador GPIO
  GPIO_DIR  = GPIO_BASE + 0x04    # registrador de direção
  GPIO_OUT  = GPIO_BASE + 0x08    # registrador de saída

  *(GPIO_DIR) = 0x01              # pin 0 como saída
  *(GPIO_OUT) = 0x01              # pin 0 = HIGH (LED aceso)

  + Usa instruções normais de load/store (sem instruções especiais)
  + Funciona com qualquer linguagem (C, Assembly, etc.)
  + Proteção via page table (SO controla acesso)
  - "Rouba" espaço de endereçamento da RAM

  Usado: ARM, MIPS, RISC-V, dispositivos modernos

PORT-MAPPED I/O (Isolated I/O):
  Espaço de endereçamento separado para I/O.
  Instruções especiais: IN, OUT (x86).

  # x86 Assembly — lendo do teclado
  in  al, 0x60     # lê porta 0x60 (teclado) para registrador AL
  out 0x61, al     # escreve registrador AL na porta 0x61

  + Não rouba espaço de endereçamento da RAM
  - Precisa de instruções especiais
  - Só funciona em Assembly ou com wrappers do SO

  Usado: x86 (legado), mas x86 moderno usa MMIO para a maioria

Padrões de Barramento Modernos

Padrões de Barramento — Comparação
Padrão      Tipo          Bandwidth (máx)    Uso principal
──────────  ────────────  ─────────────────  ─────────────────────
PCIe 4.0    Serial        ~32 GB/s (x16)     GPU, NVMe SSD, rede
PCIe 5.0    Serial        ~64 GB/s (x16)     GPU high-end, storage
PCIe 6.0    Serial        ~128 GB/s (x16)    Data centers (2024+)

DDR4        Paralelo      ~25 GB/s (dual)    Memória RAM
DDR5        Paralelo      ~50 GB/s (dual)    Memória RAM (2022+)

USB 2.0     Serial        480 Mb/s           Teclado, mouse, legacy
USB 3.2     Serial        20 Gb/s            Storage externo
USB 4       Serial        40-80 Gb/s         Thunderbolt, displays

SATA III    Serial        6 Gb/s             HDD, SSD SATA
NVMe/PCIe   Serial        ~7 GB/s (PCIe 4)   SSD de alta performance

Ethernet    Serial        1-400 Gb/s         Rede
Thunderbolt Serial        40-80 Gb/s         Periféricos Apple/Intel

Evolução:
  Paralelo → Serial:
    Barramentos paralelos (PCI, ATA) tinham problemas de
    clock skew entre as linhas. Barramentos seriais (PCIe, SATA, USB)
    usam encoding + alta frequência para superar barramentos paralelos.

  PCIe é ponto-a-ponto, não barramento compartilhado:
    Cada dispositivo tem sua conexão dedicada ("lane").
    x1 = 1 lane, x4 = 4 lanes, x16 = 16 lanes.
    Sem contenção de barramento.

Desempenho de E/S

Métricas de Desempenho de I/O
Duas métricas fundamentais:

BANDWIDTH (Throughput):
  Quantidade de dados transferidos por segundo.
  Exemplo: SSD NVMe = 7 GB/s, HDD = 200 MB/s
  Importante para: transferências grandes (vídeo, backup, ML datasets)

LATÊNCIA:
  Tempo para completar uma única operação de I/O.
  Exemplo: SSD NVMe = 20 μs, HDD = 5 ms
  Importante para: acessos aleatórios (database, boot, compilação)

IOPS (I/O Operations Per Second):
  Número de operações por segundo.
  IOPS = 1 / Latência (para operações sequenciais simples)
  Exemplo: SSD NVMe = 500.000 IOPS, HDD = 100 IOPS

Comparação prática:
  Dispositivo   Bandwidth    Latência    IOPS
  ───────────   ─────────    ────────    ──────────
  HDD SATA      200 MB/s     5-10 ms     100-200
  SSD SATA      550 MB/s     50-100 μs   90.000
  SSD NVMe      3-7 GB/s     10-30 μs    500.000+
  RAM DDR5      50 GB/s      50-100 ns   N/A
  Cache L1      1 TB/s       1-2 ns      N/A

A hierarquia de armazenamento segue o mesmo padrão da
hierarquia de memória: mais rápido = mais caro = menor.

No harness.os

Barramentos conectam componentes — são a infraestrutura de comunicação. O harness.os usa MCP (Model Context Protocol) como seu barramento: uma interface padronizada que conecta agentes, ferramentas e knowledge bases.

Mapeamento: Barramentos/E/S → harness.os
Barramentos                       harness.os
─────────────────────────────     ──────────────────────────────────────
Barramento de dados               MCP tool call (payload)
  Transporta dados entre             Transporta parâmetros e respostas
  CPU e dispositivos                 entre agente e ferramentas

Barramento de controle            MCP protocol headers
  Sinais Read/Write/IRQ              Tool name, method, metadata

Memory-mapped I/O                 MCP over stdio
  Dispositivos no espaço de          Tools acessíveis como funções
  endereçamento normal               normais no contexto do agente

Polling                           Token-by-token streaming
  CPU verifica status em loop        Agente aguarda resposta do tool

Interrupções                      Webhooks / Callbacks
  Dispositivo avisa a CPU            Serviço externo avisa o agente
  quando tem dado pronto             quando resultado está pronto

DMA                               Background agents
  Transferência sem CPU              Sub-agents executam em paralelo
  CPU continua trabalhando           Agente principal continua

Padrões de barramento             Transportes MCP
  PCIe, USB, SATA                    stdio, SSE, HTTP
  Diferentes velocidades             Diferentes latências e capacidades

Bandwidth de I/O                  Context window throughput
  GB/s de dados transferidos         Tokens/segundo processados
  Gargalo = barramento mais lento    Gargalo = tool call mais lento

Homework

  1. Um disco SSD NVMe tem bandwidth de 3.5 GB/s e latência de 20 microsegundos. Quantos IOPS (operações de 4 KB) ele consegue? Compare com um HDD de 200 IOPS. Quantas vezes o SSD é mais rápido em IOPS?
  2. Explique por que DMA é essencial para transferências de disco: se a CPU rodando a 3 GHz fizesse programmed I/O para transferir 1 GB em palavras de 8 bytes, quantas iterações seriam necessárias? Quanto tempo isso levaria se cada iteração usa 10 ciclos?
  3. No pseudocódigo de memory-mapped I/O, o que aconteceria se o endereço do GPIO fosse cacheado pela cache L1? Por que endereços de MMIO precisam ser marcados como "uncacheable"?
  4. No harness.os, o MCP usa stdio como transporte (análogo a barramento serial). Quais seriam as vantagens de usar HTTP (análogo a barramento de rede)? Quando cada transporte é mais apropriado?

Resumo

Verifique seu entendimento

Qual mecanismo de E/S permite que um dispositivo transfira dados diretamente para a memória RAM sem envolver a CPU?

  • Polling — a CPU verifica o status do dispositivo em loop
  • Interrupções — o dispositivo avisa a CPU quando tem dados prontos
  • DMA — o controlador DMA assume o barramento e transfere dados diretamente
  • Memory-mapped I/O — o dispositivo é acessado como endereço de memória