dev/perf-host-debug-overlay-isolation #14
@ -1,27 +1,37 @@
|
||||
---
|
||||
id: LSN-0026
|
||||
ticket: perf-runtime-telemetry-hot-path
|
||||
title: Modelo de Telemetria Push-based
|
||||
title: Push-based Telemetry Model
|
||||
created: 2026-04-10
|
||||
tags: [performance, telemetry, atomics]
|
||||
---
|
||||
# Modelo de Telemetria Push-based
|
||||
O sistema de telemetria do PROMETEU evoluiu de um modelo de varredura sob demanda (pull) para um modelo de contadores incrementais (push), visando minimizar o impacto no *hot path* do runtime.
|
||||
## O Problema Original
|
||||
Anteriormente, a cada *host tick*, o runtime solicitava informações de uso de memória dos bancos de assets. Isso resultava em:
|
||||
- Varreduras $O(n)$ sobre mapas de recursos.
|
||||
- Múltiplas aquisições de *locks* de leitura em cada tick.
|
||||
- Overhead desnecessário em hardwares handheld, onde cada microssegundo conta.
|
||||
## A Solução: Modelo Push com Atômicos
|
||||
A solução implementada utiliza `AtomicUsize` nos drivers e na VM para manter o estado do sistema em tempo real com custo $O(1)$ de leitura e escrita:
|
||||
1. **Drivers (Assets):** Contadores atômicos em cada `BankPolicy` são atualizados durante `load`, `commit` e `cancel`.
|
||||
2. **VM (Heap):** Um contador `used_bytes` na struct `Heap` rastreia alocações e liberações (sweep).
|
||||
3. **System (Logs):** O `LogService` rastreia a pressão de logs emitida em cada frame.
|
||||
## Dois Níveis de Observabilidade
|
||||
Para equilibrar performance e depuração, a coleta foi dividida:
|
||||
- **Snapshot de Frame (Sempre):** Captura automática no fim de cada frame lógico. Custo irrelevante ($O(1)$). Serve ao `Certifier` e ao log histórico.
|
||||
- **Tick de Host (Sob Demanda):** A coleta detalhada em cada tick só ocorre se `inspection_active` estiver habilitado (ex: Overlay F1 ligado).
|
||||
## Lições Aprendidas
|
||||
- **Desacoplamento de Gatilhos:** Não devemos usar o estado do `Certifier` para habilitar funcionalidades de depuração visual (como o overlay), pois eles têm propósitos e custos diferentes.
|
||||
- **Consistência Eventual é Suficiente:** Para métricas de telemetria, não é necessário travar o sistema para obter um valor exato a cada nanossegundo. A leitura relaxada de atômicos é suficiente e muito mais performática.
|
||||
- **Isolamento de Custo:** Mover a lógica de agregação para o driver simplifica o runtime e garante que o custo de telemetria seja pago apenas durante mutações de estado, e não repetidamente durante a execução estável.
|
||||
|
||||
# Push-based Telemetry Model
|
||||
|
||||
The PROMETEU telemetry system evolved from an on-demand scan model (pull) to an incremental counter model (push), aiming to minimize the impact on the runtime's hot path.
|
||||
|
||||
## The Original Problem
|
||||
|
||||
Previously, at every host tick, the runtime requested memory usage information from the asset banks. This resulted in:
|
||||
- $O(n)$ scans over resource maps.
|
||||
- Multiple read lock acquisitions in every tick.
|
||||
- Unnecessary overhead on handheld hardware, where every microsecond counts.
|
||||
|
||||
## The Solution: Push Model with Atomics
|
||||
|
||||
The implemented solution uses `AtomicUsize` in drivers and the VM to maintain the system state in real-time with $O(1)$ read and write cost:
|
||||
1. **Drivers (Assets):** Atomic counters in each `BankPolicy` are updated during `load`, `commit`, and `cancel`.
|
||||
2. **VM (Heap):** A `used_bytes` counter in the `Heap` struct tracks allocations and deallocations (sweep).
|
||||
3. **System (Logs):** The `LogService` tracks log pressure emitted in each frame.
|
||||
|
||||
## Two Levels of Observability
|
||||
|
||||
To balance performance and debugging, the collection was divided:
|
||||
- **Frame Snapshot (Always):** Automatic capture at the end of each logical frame. Irrelevant cost ($O(1)$). Serves the `Certifier` and historical logs.
|
||||
- **Host Tick (On-Demand):** Detailed collection in every tick only occurs if `inspection_active` is enabled (e.g., F1 Overlay on).
|
||||
|
||||
## Lessons Learned
|
||||
|
||||
- **Trigger Decoupling:** We should not use the `Certifier` state to enable visual debugging features (like the overlay), as they have different purposes and costs.
|
||||
- **Eventual Consistency is Sufficient:** For telemetry metrics, it is not necessary to lock the system to obtain an exact value every nanosecond. Relaxed atomic reading is sufficient and much more performant.
|
||||
- **Cost Isolation:** Moving the aggregation logic to the driver simplifies the runtime and ensures that the telemetry cost is paid only during state mutations, rather than repeatedly during stable execution.
|
||||
|
||||
@ -1,99 +0,0 @@
|
||||
---
|
||||
id: AGD-0007
|
||||
ticket: perf-runtime-telemetry-hot-path
|
||||
title: Agenda - [PERF] Runtime Telemetry Hot Path
|
||||
status: open
|
||||
created: 2026-03-27
|
||||
resolved:
|
||||
decision:
|
||||
tags: []
|
||||
---
|
||||
|
||||
# Agenda - [PERF] Runtime Telemetry Hot Path
|
||||
|
||||
## Problema
|
||||
|
||||
O runtime cobra telemetria de asset bank no caminho quente de todo host tick.
|
||||
|
||||
Hoje, `tick()` consulta `bank_info()` para `gfx` e `audio` mesmo quando nenhum logical frame foi fechado. O custo de observabilidade acaba sendo pago continuamente pela execucao normal.
|
||||
|
||||
## Dor
|
||||
|
||||
- CPU e locks sao gastos em todos os ticks, nao apenas quando a metrica muda.
|
||||
- hardware barato sofre mais com trabalho pequeno e repetitivo do que com picos raros.
|
||||
- overlay, stats e certifier acabam puxando custo estrutural para o core do runtime.
|
||||
|
||||
## Hotspots Atuais
|
||||
|
||||
- [tick.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-system/src/virtual_machine_runtime/tick.rs#L167)
|
||||
- [asset.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-drivers/src/asset.rs#L618)
|
||||
|
||||
## Alvo da Discussao
|
||||
|
||||
Remover varredura e agregacao lock-heavy do hot path do tick sem perder observabilidade util.
|
||||
|
||||
## O Que Precisa Ser Definido
|
||||
|
||||
1. Modelo de metrica.
|
||||
Decidir o que passa a ser contador incremental e o que continua sendo snapshot sob demanda.
|
||||
|
||||
2. Frequencia de coleta.
|
||||
Decidir se atualizacao acontece:
|
||||
- no fechamento do logical frame;
|
||||
- apenas com overlay/debug ativo;
|
||||
- por amostragem periodica;
|
||||
- por evento de mutacao (`load`, `commit`, `cancel`).
|
||||
|
||||
3. Responsabilidade da agregacao.
|
||||
Delimitar se a verdade dos bytes/slots fica:
|
||||
- no `AssetManager`;
|
||||
- no runtime;
|
||||
- em uma camada propria de telemetry cache.
|
||||
|
||||
4. Garantia de consistencia.
|
||||
Decidir qual grau de defasagem e aceitavel para handheld barato:
|
||||
- exato em tempo real;
|
||||
- eventual por frame;
|
||||
- eventual por tick de debug.
|
||||
|
||||
## Open Questions de Arquitetura
|
||||
|
||||
1. O certifier realmente precisa de snapshot de bank a cada tick?
|
||||
Não. O certifier aceita dados do fim do frame anterior, pois violações de limites de bank costumam ser persistentes entre frames.
|
||||
2. O overlay pode ler uma versao resumida da telemetria em vez de recalcular tudo?
|
||||
Sim. O `AssetManager` passará a prover uma struct `BankStats` pré-calculada via contadores atômicos.
|
||||
3. Vale manter caminho "preciso" so para testes/debug e caminho "barato" para runtime normal?
|
||||
Sim, mas a "precisão" será definida como "atualizado no último evento de mutação", o que já é suficiente para ambos os casos.
|
||||
4. Como detectar o modo de depuração/inspeção de forma correta e desacoplada?
|
||||
Através de um novo campo `inspection_active: bool` no `VirtualMachineRuntime`, controlado explicitamente pelo Host (ex: quando o Overlay F1 ou o Debugger remoto estão ativos). O `certifier` não deve ser usado para este propósito.
|
||||
|
||||
## Sugestao / Recomendacao
|
||||
|
||||
1. **Modelo de Métrica (Push-based):**
|
||||
- Migrar de snapshot total $O(n)$ para contadores incrementais $O(1)$ no `AssetManager`.
|
||||
- Utilizar `AtomicUsize` ou campos protegidos por Mutex simples para `used_bytes`, `inflight_bytes` e `slots_occupied`.
|
||||
- Atualizar esses contadores apenas em eventos de mutação (`load`, `commit`, `cancel`).
|
||||
|
||||
2. **Frequência de Coleta (Dois Níveis):**
|
||||
- **Básica (Sempre):** O Runtime deve atualizar `telemetry_current` no fechamento de cada logical frame (`FrameSync` ou `EndOfRom`). Isso garante dados para o `certifier` com custo $O(1)$.
|
||||
- **Alta Frequência (Sob Demanda):** Manter atualização em todo host tick apenas se `inspection_active` for `true` (Overlay F1 visível ou Debugger conectado).
|
||||
|
||||
3. **Responsabilidade da Agregação (Centralizada):**
|
||||
- O `AssetManager` é o dono da "verdade incremental". O Runtime consome um snapshot barato (struct POD) sem varredura de locks.
|
||||
|
||||
4. **Garantia de Consistência (Eventual):**
|
||||
- Aceitar defasagem de até 1 frame lógico para métricas de asset bank.
|
||||
|
||||
## Dependencias
|
||||
|
||||
- `../specs/10-debug-inspection-and-profiling.md`
|
||||
- `../specs/16a-syscall-policies.md`
|
||||
|
||||
## Criterio de Saida Desta Agenda
|
||||
|
||||
Pode virar PR quando houver decisao escrita sobre:
|
||||
|
||||
- metrica incremental vs snapshot;
|
||||
- ponto canonico de atualizacao da telemetria;
|
||||
- custo maximo aceitavel no hot path do tick;
|
||||
- comportamento de overlay/certifier sobre dados defasados.
|
||||
@ -1,57 +0,0 @@
|
||||
---
|
||||
id: DEC-0005
|
||||
title: "Decisão - [PERF] Modelo de Telemetria Push-based"
|
||||
status: closed
|
||||
created: 2026-03-27
|
||||
resolved: 2026-03-27
|
||||
agenda: AGD-0007
|
||||
tags: []
|
||||
---
|
||||
|
||||
# Decisão - [PERF] Modelo de Telemetria Push-based
|
||||
|
||||
## Status
|
||||
|
||||
**Fechada (Closed)** - Consensus reached. Implementation approved.
|
||||
|
||||
## Contexto
|
||||
|
||||
O runtime atual (`VirtualMachineRuntime::tick()`) realiza a coleta de telemetria de asset banks (`gfx` e `audio`) em todos os *host ticks*. Essa coleta envolve a chamada de `bank_info()` no `AssetManager`, que executa uma varredura $O(n)$ sobre mapas de recursos e adquire múltiplos locks de leitura. Em hardwares limitados (handhelds), esse custo repetitivo no caminho quente degrada a performance desnecessariamente, mesmo quando o sistema está estável ou em pausa.
|
||||
|
||||
## Decisão
|
||||
|
||||
1. **Modelo de Contadores no Driver e Runtime:** O `AssetManager`, a `Heap` da VM e o `LogService` devem substituir a varredura/contagem total por **contadores atômicos** (`used_bytes`, `inflight_bytes`, `slots_occupied`, `logs_count`) para cada subsistema. Esses contadores serão atualizados incrementalmente ($O(1)$) em cada mutação (load, commit, alloc, free, log).
|
||||
2. **Snapshot Obrigatório de Fim de Frame:** O runtime capturará o estado desses contadores (Banks, Heap e Logs) **apenas uma vez** por fechamento de frame lógico (`FrameSync` ou `EndOfRom`). Este snapshot será usado para alimentar a `telemetry_last` e o `certifier`.
|
||||
3. **Coleta sob Demanda (Inspection Mode):** A coleta em cada *host tick* será reativada **somente** se o novo sinalizador `inspection_active: bool` do runtime for verdadeiro.
|
||||
4. **Desacoplamento do Certifier:** A ativação do `certifier` não habilitará mais a telemetria detalhada em cada tick. O certifier será servido exclusivamente pelos snapshots de fim de frame lógico.
|
||||
|
||||
## Rationale
|
||||
|
||||
* **Performance:** Reduz o custo do tick do runtime de $O(n)$ com locks para $O(1)$ sem locks no modo normal.
|
||||
* **Observabilidade:** Mantém dados precisos para o overlay (via modo inspeção) e dados válidos para o certifier (via snapshot de frame).
|
||||
* **Modularidade:** Desacopla as necessidades de depuração (Overlay F1) das necessidades de validação normativa (Certifier).
|
||||
|
||||
## Invariantes / Contrato
|
||||
|
||||
* O `AssetManager` é a única fonte da verdade para o uso de memória de assets; o runtime não deve tentar calcular esses valores manualmente.
|
||||
* Contadores atômicos garantem que o runtime possa ler estatísticas de bancos sem travar mutações em andamento (consistência eventual).
|
||||
* A defasagem de até 1 frame lógico é aceitável para métricas de assets bank no modo de operação normal.
|
||||
|
||||
## Impactos
|
||||
|
||||
* **Drivers:** Necessidade de adicionar e gerenciar contadores no `AssetManager`.
|
||||
* **Virtual Machine:** Adicionar contador atômico de `used_bytes` na `Heap`.
|
||||
* **Log Service:** Adicionar contador incremental de logs emitidos no frame no `LogService`.
|
||||
* **Runtime:** Modificação no `VirtualMachineRuntime` para incluir o campo `inspection_active` e lógica condicional no `tick()`.
|
||||
* **Host:** O host (ex: desktop-winit) deve agora sinalizar quando o overlay de depuração está ativo via `inspection_active`.
|
||||
|
||||
## Referências
|
||||
|
||||
* Agenda [AGD-0007-perf-runtime-telemetry-hot-path.md](../agendas/AGD-0007-perf-runtime-telemetry-hot-path.md)
|
||||
* Spec `10-debug-inspection-and-profiling.md`
|
||||
|
||||
## Propagação Necessária
|
||||
|
||||
* Atualizar o `VirtualMachineRuntime` para expor o campo `inspection_active`.
|
||||
* Atualizar o `HostRunner` para sinalizar `inspection_active` quando o overlay F1 for alternado.
|
||||
* Atualizar a struct `TelemetryFrame` para incluir campos de Heap Memory e Log count.
|
||||
@ -1,81 +0,0 @@
|
||||
---
|
||||
id: PLN-0005
|
||||
title: "Plano - [PERF] Implementação de Telemetria Push-based"
|
||||
status: open
|
||||
created: 2026-03-27
|
||||
origin_decisions:
|
||||
- DEC-0005
|
||||
tags: []
|
||||
---
|
||||
|
||||
# Plano - [PERF] Implementação de Telemetria Push-based
|
||||
|
||||
## Briefing
|
||||
|
||||
Este plano detalha as alterações técnicas para migrar o sistema de telemetria de um modelo de varredura $O(n)$ com locks para um modelo push-based com contadores atômicos $O(1)$. O objetivo é reduzir o overhead do hot path do runtime e adicionar visibilidade sobre a memória RAM (Heap) e volume de logs.
|
||||
|
||||
## Decisions de Origem
|
||||
|
||||
* [DEC-0005 - [PERF] Modelo de Telemetria Push-based](../decisions/DEC-0005-perf-push-based-telemetry-model.md)
|
||||
|
||||
## Alvo
|
||||
|
||||
* `prometeu-drivers` (AssetManager)
|
||||
* `prometeu-vm` (Heap)
|
||||
* `prometeu-hal` (TelemetryFrame)
|
||||
* `prometeu-system` (LogService, VirtualMachineRuntime)
|
||||
* `prometeu-host-desktop-winit` (HostRunner)
|
||||
|
||||
## Escopo
|
||||
|
||||
1. **Contadores Atômicos:** Implementação de `AtomicUsize` nos subsistemas de assets, heap e logs.
|
||||
2. **Telemetry Frame:** Expansão da struct para incluir `heap_used`, `heap_max` e `logs_count`.
|
||||
3. **Lógica de Tick:** Refatoração do `tick.rs` para usar `inspection_active` e snapshots de fim de frame.
|
||||
4. **Sinalização do Host:** Integração do campo `inspection_active` com o acionamento do overlay F1.
|
||||
|
||||
## Fora de Escopo
|
||||
|
||||
* Migração da renderização do overlay para o host nativo (será tratado em plano derivado da AGD-0012).
|
||||
* Telemetria de FileSystem IO ou Corrotinas.
|
||||
|
||||
## Plano de Execucao
|
||||
|
||||
### Fase 1: Drivers e VM (Modelo Push)
|
||||
1. **`prometeu-drivers/src/asset.rs`:**
|
||||
- Adicionar contadores em `BankPolicy`.
|
||||
- Atualizar contadores em `load_internal`, `commit` e `cancel`.
|
||||
- Refatorar `bank_info()` para retornar os valores atômicos sem varredura.
|
||||
2. **`prometeu-vm/src/heap.rs`:**
|
||||
- Adicionar contador `used_bytes` na struct `Heap`.
|
||||
- Atualizar contador em `alloc()` e `free()`.
|
||||
3. **`prometeu-system/src/log.rs`:**
|
||||
- Adicionar contador `logs_count` (resetável por frame) no `LogService`.
|
||||
|
||||
### Fase 2: HAL e Runtime (Contrato e Lógica)
|
||||
1. **`prometeu-hal/src/telemetry.rs`:**
|
||||
- Adicionar `heap_used_bytes`, `heap_max_bytes` e `logs_count` na `TelemetryFrame`.
|
||||
2. **`prometeu-system/src/virtual_machine_runtime.rs`:**
|
||||
- Adicionar campo `public inspection_active: bool`.
|
||||
3. **`prometeu-system/src/virtual_machine_runtime/tick.rs`:**
|
||||
- Modificar `tick()` para coletar `bank_info` detalhado apenas se `inspection_active == true`.
|
||||
- Implementar a captura do snapshot consolidado no fechamento do logical frame.
|
||||
|
||||
### Fase 3: Host e Integração
|
||||
1. **`prometeu-host-desktop-winit/src/runner.rs`:**
|
||||
- Sincronizar o estado do campo `overlay_enabled` com `firmware.os.inspection_active`.
|
||||
|
||||
## Criterios de Aceite
|
||||
|
||||
* O sistema compila sem avisos de tipos inexistentes.
|
||||
* A telemetria de assets (`gfx`/`audio`) continua funcional no overlay F1.
|
||||
* Novos campos de Heap e Logs aparecem no log de performance do console.
|
||||
* O custo de telemetria no `tick` deve cair drasticamente quando o overlay estiver desligado (verificável via profiling).
|
||||
|
||||
## Tests / Validacao
|
||||
|
||||
* **Teste Unitário:** Criar teste em `asset.rs` para garantir que contadores batem com a realidade após sequências de carga e cancelamento.
|
||||
* **Teste de Regressão:** Garantir que o `certifier` continua detectando violações de bank no fim do frame.
|
||||
|
||||
## Riscos
|
||||
|
||||
* **Consistência Eventual:** Como os contadores são atômicos e não travam o sistema, pode haver uma defasagem momentânea durante um `commit` pesado; isto é aceitável conforme DEC-0005.
|
||||
Loading…
x
Reference in New Issue
Block a user