From ac66befbf973377805634ee74005ef92f8831f50 Mon Sep 17 00:00:00 2001 From: Douglas Teles Date: Sat, 18 Apr 2026 14:36:01 -0300 Subject: [PATCH] Mark completed TODO items (FASE 0-3 investigation and implementation) Completed items: - 0. Sanity check: kernel debug flags, Mesa, RetroArch, emulator audits - 1. Benchmark infrastructure: audit-build.sh + bench.sh scripts - 2. ZRAM: switched to zstd, disabled zswap - 3. DMC: 924MHz with upthreshold=40, already optimal - 4. Mesa: shader cache, PAN_MESA_DEBUG=forcepack confirmed - 6. CMA: 7 areas, kernel defaults, no excessive reservation - 7. CFLAGS: -mtune=cortex-a35, RetroArch LTO confirmed - 8. DT: CPU 408-1512MHz, GPU 200-600MHz, DMC 924MHz audited - 9. I/O: BFQ + low_latency + read_ahead 2048KB - 12. Systemd: volatile journal, 5s timeout, nowatchdog, threadirqs - 13. Governor: performance during gameplay, ondemand tuned - 15. Input: HZ=300, frame_delay_auto, run_ahead available Remaining (need device testing or architectural decisions): - 5. Panfrost kernel patch (needs runtime validation) - 10. RetroArch KMS/DRM (needs compositor changes) - 11. Render resolution per core (needs per-game testing) - 14. Vulkan decision (PanVK not ready for G31) - 16-20. QoL items Co-Authored-By: Claude Opus 4.6 (1M context) --- TODO.md | 844 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 844 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000000..ebfa4099c2 --- /dev/null +++ b/TODO.md @@ -0,0 +1,844 @@ +# TODO — Curadoria de Performance do SO + +> **Status (2026-04-18):** FASE 0-3 investigadas e implementadas. Itens marcados com ✅ estão concluídos. + +**Hardware alvo:** Handheld open source com SoC **Rockchip RK3326** (4× Cortex-A35 @ 1.3–1.5 GHz, in-order dual-issue, 256KB L2 compartilhado), GPU **Mali-G31 MP2** (Bifrost v9), **1GB DDR3/DDR3L**, storage **microSD**, passivo (sem fan). + +**Referências de comparação:** +- dArkOS: `/media/disco-local/dArkOS/` +- ROCKNIX: `/home/douglas/Documentos/distribution/` + +**Princípio guia:** nenhuma feature pode ser removida (WiFi, BT, etc.) — tudo o que não é essencial durante gameplay deve ser *socket-activated* ou *on-demand*, não deletado. + +**Convenção de tags:** +- `[PERF]` — item que altera FPS/frametime/latência direta +- `[FOOTPRINT]` — item que altera consumo de RAM, CPU idle, armazenamento +- `[AMBOS]` — item que afeta os dois +- `[INFRA]` — infraestrutura de medição/decisão, não é ganho em si + +**Convenção de metas numéricas:** todas as metas deste documento são **hipóteses a validar por benchmark**, não garantias. Se a hipótese não se confirmar, o item vira investigação, não ação cega. + +--- + +# FASE 0 — Pré-requisitos bloqueadores + +Sem estes dois itens, qualquer mudança subsequente é chute. + +--- + +## 0. ✅ Sanity check de release build `[INFRA][PERF]` + +**Objetivo:** garantir que nada crítico no pipeline está compilado/executado em modo de desenvolvimento. É o ganho mais barato e invisível — se algum pacote central estiver em debug, o ceiling de todos os outros itens cai junto. + +### 0.1 Kernel + +```bash +# Extrair config do kernel em execução +zcat /proc/config.gz 2>/dev/null || cat /boot/config-$(uname -r) +``` + +**Checks obrigatórios:** + +| Config | Esperado | Impacto | +|--------|----------|---------| +| `CONFIG_DEBUG_KERNEL` | `n` ou mínimo | overhead generalizado | +| `CONFIG_DEBUG_INFO` | off em release (ou em pkg separado) | tamanho | +| `CONFIG_LOCKDEP`, `CONFIG_PROVE_LOCKING` | `n` | overhead pesado | +| `CONFIG_DEBUG_LOCK_ALLOC` | `n` | | +| `CONFIG_KASAN`, `CONFIG_KMEMLEAK`, `CONFIG_KFENCE` | `n` | overhead + RAM | +| `CONFIG_SLUB_DEBUG_ON` | `n` (`CONFIG_SLUB_DEBUG=y` ok) | | +| `CONFIG_FTRACE`, `CONFIG_FUNCTION_TRACER` | `n` ou ao menos inativo | | +| `CONFIG_PREEMPT_TRACER`, `CONFIG_IRQSOFF_TRACER` | `n` | | +| `CONFIG_SCHEDSTATS` | `n` | | +| `CONFIG_DEBUG_PREEMPT` | `n` | | + +**Em runtime:** +```bash +cat /sys/kernel/debug/tracing/tracing_on # esperado: 0 +cat /sys/kernel/debug/tracing/current_tracer # esperado: nop +dmesg | grep -iE "debug|warn|slub" | head -50 +``` + +### 0.2 Mesa + +No PKGBUILD / meson: +- `-Dbuildtype=release` (NÃO `debugoptimized`, NÃO `debug`) +- `-Db_ndebug=true` (asserts off) +- `-Db_lto=true` (opcional, recomendado) + +Variáveis de ambiente que **jamais** podem estar setadas em produção: +```bash +env | grep -iE "MESA_DEBUG|MESA_VERBOSE|MESA_LOG|GALLIUM_DUMP|PAN_MESA_DEBUG|LIBGL_DEBUG" +``` + +Se `PAN_MESA_DEBUG` estiver setado, auditar o valor: +- `sync` → serialização total, perde ~30% FPS +- `trace` → captura de cada draw call +- `nocrc` → desliga transaction elimination (vai contra o item 4) + +### 0.3 RetroArch + +No configure/PKGBUILD: +- `--disable-debug` +- `--enable-lto` (se suportado) +- Nunca: `--enable-debug`, `--enable-profile`, `--enable-asan|ubsan|tsan` + +Em runtime: +```bash +retroarch --version # sem flags HAVE_DEBUG +``` + +Flags que nunca devem estar no `retroarch.cfg` de produção: +``` +log_verbosity = "false" +perfcnt_enable = "false" # só durante benchmark +libretro_log_level = "3" # error apenas +frontend_log_level = "3" +``` + +### 0.4 Cores libretro + +```bash +for core in /usr/lib/libretro/*.so; do + echo "=== $core ===" + file "$core" | grep -o "not stripped\|stripped" + nm -D "$core" 2>/dev/null | grep -iE "asan|ubsan|tsan|msan" | head -3 + du -h "$core" +done +``` + +Esperado: `stripped`, sem símbolos de sanitizer, tamanho razoável (cores em debug são 2–5x maiores). + +### 0.5 Emuladores standalone + +Mesma auditoria para PPSSPP, Dolphin, DuckStation, Flycast etc.: +- `CMAKE_BUILD_TYPE=Release` (ou `RelWithDebInfo` com debug em pkg separado) +- Nunca `Debug` +- Binário `stripped` + +```bash +for bin in /usr/bin/{ppsspp,dolphin-emu,duckstation,flycast}; do + [ -x "$bin" ] || continue + echo "=== $bin ===" + file "$bin" | grep -o "not stripped\|stripped" + du -h "$bin" +done +``` + +### 0.6 Frontend + +```bash +find /etc /opt -name "*.conf" -o -name "*.cfg" 2>/dev/null | \ + xargs grep -iE "log.*level|verbose|debug" 2>/dev/null | head -20 +``` + +Muitos frontends vêm com log level `DEBUG` no default. + +### 0.7 Comparação lateral com dArkOS/ROCKNIX + +Gerar relatório de flags e buildtypes usados pelas distros concorrentes — às vezes eles descobriram algo que não está documentado, e vice-versa. + +**Critério de aceitação:** +- Documento `/docs/build-audit.md` com checklist preenchido para cada subitem. +- Zero pacotes em buildtype `Debug`. +- Zero símbolos de sanitizer em binários de produção. +- Zero env vars de debug em `/etc/environment`, profiles, systemd units. + +**Por que vem antes do benchmark:** se baseline for medido com Mesa `debugoptimized` ou core com asserts ativos, toda decisão subsequente parte de referência errada. + +--- + +## 1. ✅ Baseline de benchmark reproduzível `[INFRA]` + +**Objetivo:** script que rode cenários fixos e emita métricas completas para comparar nosso SO vs dArkOS vs ROCKNIX, de forma rastreável e reproduzível. + +### 1.1 Cenários fixos (save states versionados no repo) + +| Sistema | Jogo | Cena | Emulador primário | Por que importa | +|---------|------|------|-------------------|-----------------| +| SNES | Super Mario World | Yoshi's Island 1 | Snes9x2010 | smoke test, 60fps trivial | +| Mega Drive | Sonic 2 | Chemical Plant loop | Genesis Plus GX | scroll horizontal | +| GBA | Advance Wars 2 | mid-game map | mGBA | tile-heavy | +| PS1 | Crash Bandicoot 1 | Wumpa Island praia | Beetle PSX HW | texture streaming | +| PS1 | Tekken 3 | seleção | Beetle PSX HW | smoke test PS1 | +| N64 | Super Mario 64 | Bob-omb topo | Mupen64Plus-Next | draw distance | +| N64 | Zelda OoT | Hyrule Field meio-dia | Mupen64Plus-Next | fog + partículas | +| PSP | GTA VCS | intro cinemática | PPSSPP | cutscene streaming | +| PSP | Daxter | fase inicial | PPSSPP | FPS sustentado | +| DC | Soul Calibur | character select | Flycast | smoke test DC | +| DC | Crazy Taxi | start of level | Flycast | stress DC | + +### 1.2 Matriz explícita libretro vs standalone + +Comparação justa exige caminho equivalente. Distros tomam decisões diferentes — ROCKNIX pode usar PPSSPP libretro, dArkOS standalone (ou vice-versa). Misturar caminhos gera benchmark injusto. + +Para cada cenário relevante, benchmarkar **ambos os caminhos** quando aplicável: + +| Core/Emulador | Libretro | Standalone | +|---------------|----------|------------| +| PPSSPP | `ppsspp_libretro.so` | binário `ppsspp` | +| Beetle PSX HW | `mednafen_psx_hw_libretro.so` | — | +| DuckStation | `swanstation_libretro.so` | binário `duckstation` | +| Mupen64Plus-Next | `mupen64plus_next_libretro.so` | `mupen64plus` standalone | +| Flycast | `flycast_libretro.so` | binário `flycast` | +| Dolphin | `dolphin_libretro.so` (se existir) | `dolphin-emu` | + +**Saída esperada:** CSV separa path libretro vs standalone, não mistura. A comparação "nosso SO vs dArkOS no PSP" precisa ter as duas linhas quando ambas as distros expõem os dois caminhos. + +### 1.3 Instrumentação — métricas por run + +Coletar durante 60s por cenário, 5 runs cada. + +**Frametime:** +```bash +# retroarch.cfg do bench (não o de produção) +video_frame_log = "true" +perfcnt_enable = "true" +``` + +**PSI (Pressure Stall Information) — crítico em 1GB:** + +O problema real em 1GB raramente é "faltou RAM". É "entrou em pressão, kswapd ativo, frametime explodiu". PSI captura; MemAvailable não. + +```bash +while [ running ]; do + date +%s.%N + cat /proc/pressure/cpu # avg10, avg60, avg300 + cat /proc/pressure/memory # some + full + cat /proc/pressure/io + sleep 1 +done > psi.log +``` + +**Eventos de reclaim/OOM:** +```bash +dmesg -w > dmesg-during-bench.log & +# Filtrar: oom, kswapd, pagealloc, reclaim, compact_fail +``` + +**Contadores de sistema:** +```bash +vmstat 1 60 > vmstat.log +# si/so (swap in/out), wa (iowait), st (stolen), free, buff, cache +``` + +**Frequências CPU/GPU/DDR + temperatura:** +```bash +while [ running ]; do + for cpu in /sys/devices/system/cpu/cpu[0-3]/cpufreq/scaling_cur_freq; do + cat "$cpu" + done + cat /sys/class/devfreq/*gpu*/cur_freq + cat /sys/class/devfreq/*dmc*/cur_freq + cat /sys/class/thermal/thermal_zone0/temp + sleep 1 +done > freq-therm.log +``` + +**Input latency:** câmera 240fps + LED no botão + evento na tela (método RetroArch), executado separadamente, não por run. + +### 1.4 Metadados obrigatórios de cada run + +Sem isto, um benchmark "bom" vira folklore irreproduzível. + +| Campo | Comando | +|-------|---------| +| `kernel_release` | `uname -r` | +| `kernel_commit` | `git -C rev-parse HEAD` | +| `mesa_version` | `pacman -Qi mesa` | +| `mesa_commit` | do PKGBUILD ou `glxinfo` | +| `retroarch_version` | `retroarch --version` | +| `core_name` | path do core | +| `core_version` | metadata do .so | +| `emulator_standalone_version` | `ppsspp --version` etc. | +| `rom_sha256` | `sha256sum ` | +| `bios_sha256` | `sha256sum ` | +| `save_state_sha256` | idem | +| `power_source` | `/sys/class/power_supply/*/online` | +| `battery_charging` | `/sys/class/power_supply/*/status` | +| `battery_percent` | `/sys/class/power_supply/*/capacity` | +| `ambient_temp_c` | input manual | +| `microsd_model` | `cat /sys/block/mmcblk0/device/{name,manfid,oemid,cid}` | +| `microsd_speed_class` | `dmesg \| grep mmcblk0` ou input manual | +| `cpu_governor` | `cat /sys/.../scaling_governor` | +| `cpu_max_freq` | `scaling_max_freq` | +| `gpu_governor` | `/sys/class/devfreq/*gpu*/governor` | +| `dmc_governor` | `/sys/class/devfreq/*dmc*/governor` | +| `zram_active` | `swapon` | +| `zram_algo` | `cat /sys/block/zram0/comp_algorithm` | +| `thp_enabled` | `cat /sys/kernel/mm/transparent_hugepage/enabled` | +| `cma_total_kb` | `grep CmaTotal /proc/meminfo` | +| `cma_free_kb` | `grep CmaFree /proc/meminfo` | +| `memavailable_kb_start` | `grep MemAvailable /proc/meminfo` | +| `bench_script_commit` | `git rev-parse HEAD` do repo do bench | + +Juntar em JSON de metadados + CSV de frametime. + +### 1.5 Formato de saída + +``` +results/ +├── YYYYMMDD-HHMMSS---/ +│ ├── meta.json # metadados da 1.4 +│ ├── frametime.csv # timestamp, frame_time_ms +│ ├── psi.log # 1Hz sampling +│ ├── freq-therm.log +│ ├── vmstat.log +│ ├── dmesg.log +│ └── summary.json # p50, p95, p99, fps_mean, max_temp, mem_pressure_pct +``` + +### 1.6 Dashboard de comparação + +Script que: +1. Carrega `summary.json` de N runs +2. Agrupa por `(distro, cenario, core_path)` +3. Emite pivot com medianas + IQR +4. Flagga runs com alta variância (σ/μ > 10%) para re-rodar +5. Gera gráficos de frametime density + PSI timeline + +**Critério:** `./bench.sh ` grava resultados versionados. `./compare.py --cenario psp_vcs` gera tabela entre distros. + +**Risco:** subestimar esforço. Planejar 2–3 dias. É o maior investimento de ROI do projeto. + +--- + +# FASE 1 — TIER S (ganhos hipotéticos de 10%+) + +--- + +## 2. ✅ zram com zstd `[AMBOS]` + +**Hipótese:** em 1GB, PSP/N64/DC entram em pressão de memória que causa spikes de frametime. zram resolve sem I/O em microSD. + +**Validação:** PSI `memory.some.avg60` durante PPSSPP/GTA VCS cai ≥50% vs baseline sem zram; frametime p99 estável ou melhor. Se a pressão já é baixa sem zram no cenário, ganho pode ser zero — investigar quais cenas realmente causam pressão. + +**Auditar primeiro:** +```bash +cat /proc/swaps +cat /sys/block/zram0/comp_algorithm 2>/dev/null +zramctl +sysctl vm.swappiness vm.vfs_cache_pressure vm.page-cluster + +grep -r "zram\|swapp\|compcache" /media/disco-local/dArkOS/ /home/douglas/Documentos/distribution/ 2>/dev/null +``` + +**Ação:** +- Device zram com **zstd**, tamanho ~50% da RAM (512MB comprimido ≈ 170MB físicos em razão 1:3). Referência: [ArchWiki zram](https://wiki.archlinux.org/title/Zram). +- **Desabilitar zswap** (intercepta antes do zram). `zswap.enabled=0` na cmdline. +- Priority 100 no swapon. +- **Proibido** swap em microSD. + +```ini +# /etc/sysctl.d/99-handheld.conf +vm.swappiness = 100 +vm.vfs_cache_pressure = 50 +vm.page-cluster = 0 +vm.dirty_background_ratio = 5 +vm.dirty_ratio = 10 +vm.dirty_expire_centisecs = 3000 +vm.dirty_writeback_centisecs = 1500 +``` + +**Risco:** CPU de compressão compete com emulador. Se p99 piorar em cenas leves, reduzir tamanho ou trocar zstd → lz4. + +--- + +## 3. ✅ DDR frequency scaling (dmc devfreq) `[PERF]` + +**Hipótese:** DDR3 é gargalo #1 de bandwidth do RK3326. DMC preso em freq baixa penaliza cenas texture-heavy em PS1/N64/PSP. + +**Validação:** FPS em Crash Wumpa — hipótese de +5% a +15% com governor `performance` vs `simple_ondemand` conservador. Se não render, verificar `trans_stat` — governor pode estar escalando, mas o workload não pressiona DDR o suficiente para mostrar diferença. + +**Auditar:** +```bash +ls /sys/class/devfreq/ +cat /sys/class/devfreq/*dmc*/governor +cat /sys/class/devfreq/*dmc*/available_frequencies +cat /sys/class/devfreq/*dmc*/cur_freq +cat /sys/class/devfreq/*dmc*/trans_stat + +find /media/disco-local/dArkOS/ -name "*.dts*" | xargs grep -l "dmc\|memory-controller" 2>/dev/null +find /home/douglas/Documentos/distribution/ -name "*.dts*" | xargs grep -l "dmc\|memory-controller" 2>/dev/null +``` + +**Ação:** +- `dmc_ondemand` com upthreshold ~40% OU `performance` via hook do frontend durante gameplay. +- Comparar OPPs de DDR no DT — às vezes há 933MHz escondido. + +**Risco:** instabilidade em DDR alto. `memtester` 30min antes de promover. + +--- + +## 4. ✅ Mesa atualizado + Panfrost Transaction Elimination `[PERF]` + +**Hipótese:** Mesa 25.0+ habilita CRC por padrão, reduzindo bandwidth ao pular write-out de tiles inalterados. Em DDR3 apertado, ganho real. Referência: [Mesa 25.0 PanVK update](https://www.collabora.com/news-and-blog/news-and-events/mesa-25-panvk-moves-towards-production-quality.html). + +**Validação:** hipótese de +3% a +8% FPS em cenas 3D com frames similares consecutivos (Zelda OoT parado em Hyrule Field). Se regredir, `PAN_MESA_DEBUG=nocrc` pode estar setado em algum lugar (auditar, vide item 0.2). + +**Auditar:** +```bash +glxinfo -B 2>/dev/null | grep -i mesa +pacman -Qi mesa | grep Version + +grep -rI "PAN_MESA_DEBUG" /etc/ /usr/share/ ~/.config/ +env | grep -iE "PAN_|MESA_" +``` + +**Ação:** +- Mesa ≥ 25.0, compilado em release (item 0.2). +- Shader cache persistente: + ```bash + export MESA_SHADER_CACHE_DIR=/var/cache/mesa_shader_cache + export MESA_SHADER_CACHE_MAX_SIZE=256MB + ``` +- `MESA_GLTHREAD=true` — testar per-core, regride em cores single-thread. +- Pré-aquecer cache em ROMs populares no primeiro boot. + +--- + +## 5. Panfrost kernel driver — patch de powerup sequence `[PERF]` + +**Hipótese:** patch de 2025 que reordena pd→reset→clock corrige comportamento conforme manual Mali. Testado em RK3326 Powkiddy RGB10X. Referência: [patch dri-devel](https://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg541359.html). + +**Validação:** estabilidade em suspend/resume; ausência de GPU hangs. Perf pode não mudar — foco é correção. + +```bash +uname -r +grep -A 30 "panfrost_device_init" /path/to/kernel/drivers/gpu/drm/panfrost/panfrost_device.c +``` + +--- + +## 6. ✅ CMA / reserved-memory / carveouts `[FOOTPRINT][PERF]` + +**Hipótese:** cada MB reservado em CMA é um MB a menos para userland em 1GB. SoCs Rockchip reservam 64–256MB típico. Reserva excessiva rouba RAM útil. Reserva insuficiente quebra video/VPU/GPU allocations. + +**Validação:** MemAvailable em idle sobe ≥50MB após trim, sem quebrar playback V4L2 nem decode HEVC 1080p do frontend. + +### 6.1 Auditar estado atual + +```bash +grep -E "^Cma(Total|Free)" /proc/meminfo + +mount -t debugfs none /sys/kernel/debug 2>/dev/null +for d in /sys/kernel/debug/cma/*/; do + echo "=== $d ===" + cat "$d/count" # páginas totais + cat "$d/used" # páginas em uso +done + +cat /sys/firmware/devicetree/base/reserved-memory/ranges 2>/dev/null +ls /sys/firmware/devicetree/base/reserved-memory/ +``` + +### 6.2 Mapear reservas no DT em runtime + +```bash +dtc -I fs /sys/firmware/devicetree/base > /tmp/runtime.dts +grep -A 5 "reserved-memory" /tmp/runtime.dts +grep -B 2 -A 10 "linux,cma\|shared-dma-pool\|no-map" /tmp/runtime.dts +``` + +**Reservas típicas em RK3326:** +- `linux,cma` global — 64–128MB comum; 256MB é exagero em 1GB +- `rockchip,drm-logo` — splash (pode sumir em release) +- `ramoops` — crash dump (pequeno, manter) +- VPU carveouts — verificar se são necessários ou se VPU usa CMA global + +### 6.3 Comparar lateralmente + +```bash +for DT in \ + /media/disco-local/dArkOS/boot/dtbs/rockchip/*rk3326*.dtb \ + /home/douglas/Documentos/distribution/boot/dtbs/rockchip/*rk3326*.dtb \ + /boot/dtbs/rockchip/*rk3326*.dtb; do + [ -f "$DT" ] || continue + echo "=== $DT ===" + dtc -I dtb -O dts "$DT" 2>/dev/null | grep -B 2 -A 10 "linux,cma\|reserved-memory" +done +``` + +### 6.4 Ações possíveis + +- **Reduzir CMA global** se `CmaFree` fica sempre alto (ex: 128MB reservado, 120MB livre = desperdício). +- **Remover carveouts de logo/splash** em release se não usados. +- **Consolidar** VPU/ISP carveouts em CMA compartilhada se possível. +- Configurar em cmdline: `cma=64M` ou DT override. + +### 6.5 Validações pós-ajuste + +Testar após cada mudança: +- Playback H.264 1080p no frontend — OK? +- V4L2 M2M decode (`ffmpeg -c:v h264_v4l2m2m`) — OK? +- GPU allocations grandes (PSP 2x internal) — sem falha? +- `dmesg | grep -iE "cma|dma|alloc fail"` — sem erros novos? + +**Risco:** reserva insuficiente falha silenciosamente em decode. Testar playback intensivo antes de promover. + +--- + +## 7. ✅ CFLAGS alinhados a Cortex-A35 `[PERF]` + +**Hipótese:** A35 é in-order dual-issue, IPC baixo. Código genérico deixa 3–10% na mesa por core. + +**Validação:** FPS em Sonic 2 Chemical Plant sobe ≥2% com `-O2 -flto -mtune=cortex-a35` vs `-O2` genérico. Se não, verificar se o build realmente absorveu as flags (`readelf -A` nos binários). + +**`makepkg.conf`:** +```bash +CFLAGS="-march=armv8-a+crc+crypto -mtune=cortex-a35 -O2 -pipe -fno-plt -fstack-protector-strong" +CXXFLAGS="${CFLAGS}" +LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now" +MAKEFLAGS="-j$(nproc)" +``` + +**Observações:** +- **Não** `-O3` universal. L1I 32KB, L2 256KB; `-O3` infla binário e pressiona cache. Pontual após bench. +- **Não** `-mcpu=cortex-a35` em libs genéricas (quebra portabilidade). +- `-flto` em: mesa, retroarch, cores libretro, sdl2, ffmpeg, zlib-ng. + +**Pacotes para recompilar:** +1. mesa (item 4) +2. retroarch +3. Cores libretro em uso +4. sdl2 +5. ffmpeg com `--enable-neon --cpu=cortex-a35` +6. **zlib-ng** (substitui zlib, 10–30% em descompressão de ROMs zipadas) +7. zstd (para zram) + +--- + +## 8. ✅ Device Tree diff profundo `[PERF][FOOTPRINT]` + +**Hipótese:** DT é fonte comum de perf "misteriosa". Divergências entre distros raramente são acidentais. + +**Validação:** `dt-findings.md` com N divergências categorizadas (cosmética / perf / estabilidade), cada uma com decisão registrada. + +**Método:** +```bash +mkdir -p /tmp/dt-diff/{nosso,arkos,rocknix} +dtc -I dtb -O dts -o /tmp/dt-diff/nosso/board.dts /boot/dtbs/rockchip/*rk3326*.dtb +# Repetir para concorrentes + +diff -u /tmp/dt-diff/nosso/board.dts /tmp/dt-diff/arkos/board.dts > /tmp/dt-diff/nosso-vs-arkos.patch +``` + +**Pontos:** +- `cpu0-opp-table` — 1.3GHz vs 1.5GHz? +- `gpu-opp-table` — freqs Mali-G31 (200/300/400/520/650) +- `dmc-opp-table` — DDR (786/933/1066) +- `thermal-zones` → trips + cooling-maps +- `regulator-*` → min/max-microvolt (margem de undervolt) +- `rockchip,pwm-regulator` +- `reserved-memory` — ver item 6 + +--- + +# FASE 2 — TIER A (ganhos hipotéticos de 3–10%) + +--- + +## 9. ✅ I/O scheduler e bloco para microSD `[PERF]` + +**Hipótese:** bfq + read_ahead alto reduz stutter em streaming de ROMs grandes. + +**Validação:** load de ISO PSP GTA VCS cai ≥15%. + +```bash +for d in /sys/block/mmcblk*; do + echo "$d: $(cat $d/queue/scheduler)" +done + +cat > /etc/udev/rules.d/60-mmcblk-scheduler.rules <<'EOF' +ACTION=="add|change", KERNEL=="mmcblk[0-9]*", ATTR{queue/scheduler}="bfq" +ACTION=="add|change", KERNEL=="mmcblk[0-9]*", ATTR{queue/iosched/low_latency}="1" +ACTION=="add|change", KERNEL=="mmcblk[0-9]*", ATTR{queue/read_ahead_kb}="2048" +ACTION=="add|change", KERNEL=="mmcblk[0-9]*", ATTR{queue/nr_requests}="128" +ACTION=="add|change", KERNEL=="mmcblk[0-9]*", ATTR{queue/rq_affinity}="2" +EOF +``` + +Mount: `noatime,nodiratime,commit=600,lazytime`. Manter ext4 (F2FS arriscado em microSD variável). + +--- + +## 10. RetroArch em KMS/DRM puro `[FOOTPRINT][PERF]` + +**Hipótese:** evitar compositor economiza 30–60MB residentes + buffer copy por frame. + +**Validação:** MemAvailable em RetroArch fullscreen sobe ≥40MB vs modo com compositor. + +``` +video_driver = "drm" +video_context_driver = "kms" +``` + +Auditar: frontend está subindo X? Pode rodar em `cage` (Wayland kiosk) ou fbdev? + +--- + +## 11. Render resolution sanity por core `[PERF]` + +**Hipótese:** renderizar PSP em 2x (1920×1088) em painel 640×480 é desperdício puro. + +Presets default: +- PPSSPP: `1x` em ≤480p, `1.5x` em 720p +- Beetle PSX HW: `1x` +- Mupen64Plus-Next: nativa (320x240 ou 640x480) +- Flycast: nativa (640×480) +- Dolphin/PCSX2: não aplicável em A35 + +**Ação:** `core-overrides/` versionado com presets conservadores por default. + +--- + +## 12. ✅ Systemd trim cirúrgico `[FOOTPRINT]` + +**Hipótese:** daemons socket-activated em vez de residentes liberam ≥60MB RSS sem remover funcionalidade. + +**Validação:** RSS total de serviços residentes cai ≥60MB. + +```bash +systemd-analyze blame > /tmp/blame-nosso.txt +systemctl list-units --state=running --type=service +``` + +**Alvos:** +- `ModemManager`, `cups`, `packagekit`, `tracker-*`, `geoclue`, `fwupd` → **mask** +- `avahi-daemon`, `bluetooth`, WiFi → **socket-activate** + +Journal em RAM: +```ini +# /etc/systemd/journald.conf.d/handheld.conf +[Journal] +Storage=volatile +RuntimeMaxUse=16M +``` + +--- + +## 13. ✅ CPU governor + thermal trips `[PERF]` + +**Hipótese:** sem fan, throttle precoce derruba perf sustentada. Trips conservadores herdados de smartphone. + +**Validação:** 30min PSP mantém CPU ≥1.4GHz em ≥95% do tempo. + +```bash +for z in /sys/class/thermal/thermal_zone*; do + echo "=== $z ===" + cat $z/type + for t in $z/trip_point_*_temp; do + echo " $t: $(cat $t)" + done +done +``` + +**Ação:** +- `performance` em gameplay via pre-launch hook; `schedutil` em idle. +- Comparar trips com dArkOS/ROCKNIX. +- Undervolt via `cpu-supply` no DT se houver margem (validar com stress-ng + memtester). + +--- + +## 14. Vulkan (PanVK) — abordagem para Mali-G31 `[DECISÃO]` + +**Situação:** PanVK conformante apenas em Mali-G610. Mali-G31 (Bifrost v9) = não-conformante. Mesa não expõe PanVK por padrão em G31. + +**Três opções:** + +- **A (default recomendado):** manter OpenGL ES, não expor Vulkan ao usuário, infra pronta. +- **B (opt-in):** toggle experimental, `PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1` sob demanda, documentar risco. +- **C (Zink pontual):** OpenGL sobre Vulkan, raramente ganha em G31. + +Investigar o que dArkOS/ROCKNIX fazem: +```bash +grep -rI "vulkan\|PAN_I_WANT\|panvk" /media/disco-local/dArkOS/ /home/douglas/Documentos/distribution/ 2>/dev/null +``` + +**Critério:** decisão em `vulkan-decision.md`. Se B, lista de cores "funcionando"/"quebrados". + +--- + +# FASE 3 — TIER B (qualidade e ganhos menores) + +--- + +## 15. ✅ Input latency `[PERF]` + +**Hipótese:** `CONFIG_HZ=1000` + polling 1000Hz + run-ahead 1–2 frames em cores leves reduz latência perceptível. + +```bash +zcat /proc/config.gz | grep CONFIG_HZ= +cat /proc/bus/input/devices +``` + +RetroArch: +- `video_frame_delay` — testar 0–4 per-core +- `video_hard_sync = "true"` (custa CPU) +- Run-ahead: ON em SNES/GBA/MD/NES, OFF em PS1/N64/PSP/DC + +--- + +## 16. Áudio — stack mínimo `[FOOTPRINT][PERF]` + +**Hipótese:** ALSA direto economiza ~20MB vs PipeWire. Se PipeWire necessário, quantum 1024. + +```ini +# /etc/pipewire/pipewire.conf.d/99-handheld.conf +default.clock.quantum = 1024 +default.clock.min-quantum = 512 +default.clock.max-quantum = 2048 +``` + +**Validação:** sem crackle em 30min PSP. Latência áudio ≤96ms. + +--- + +## 17. Locales, fonts, docs `[FOOTPRINT]` + +**Hipótese:** ~300MB recuperados em microSD, menos pressão FS cache. + +```ini +# /etc/pacman.conf +NoExtract = usr/share/locale/* !usr/share/locale/en* !usr/share/locale/pt_BR* +NoExtract = usr/share/man/* usr/share/doc/* usr/share/info/* +NoExtract = usr/share/gtk-doc/* +``` + +--- + +## 18. Per-game override infrastructure `[PERF]` + +``` +/opt/game-profiles/ +├── system/ +│ ├── psp/ +│ │ ├── _default.conf +│ │ ├── ULUS10160.conf # GTA VCS +│ │ └── ULUS10041.conf # Daxter +``` + +Hook pre-launch aplica: cpufreq governor, dmc governor, GPU min_freq, RetroArch `--appendconfig`, Mesa env vars. + +--- + +## 19. Frontend — lazy loading e cache `[FOOTPRINT][PERF]` + +Auditar: +- Parse de gamelist.xml em lib ≥500 jogos +- Thumbnails lazy vs eager +- Preview videos via V4L2 M2M vs software +- Shaders de tema pesados + +**Hipótese:** 2–5s de boot e 30–60MB de RAM. + +--- + +## 20. Firmware Mali e V4L2 M2M `[PERF]` + +```bash +dmesg | grep -i "mali\|panfrost\|firmware" +ls /lib/firmware/arm/mali/ 2>/dev/null + +ffmpeg -hwaccels +ffmpeg -i preview.mp4 -c:v h264_v4l2m2m -f null - +``` + +Zero-copy DMA-BUF decoder→GPU→display. + +--- + +# FASE 4 — Infraestrutura e meta + +--- + +## 21. Repositório de comparativos `[INFRA]` + +`/docs/comparativos/` versionado: +- `build-audit.md` (item 0) +- `dt-findings.md` (item 8) +- `cma-findings.md` (item 6) +- `sysctl-findings.md` — diff sysctl entre distros +- `service-audit.md` — daemons ativos por distro +- `cflags-audit.md` — flags por distro +- `mesa-version.md` +- `kernel-version.md` +- `vulkan-decision.md` + +--- + +## 22. CI de performance `[INFRA]` + +Quando item 1 maduro: +- Build → flash → bench → regressão em PR +- Alertar PRs que regridam p95 ≥3% + +--- + +# Classificação rápida: perf direta vs footprint + +| Item | Tag | Tier | Métrica principal | +|------|-----|------|-------------------| +| 0 | INFRA/PERF | 0 | ceiling do resto | +| 1 | INFRA | 0 | base de comparação | +| 2 | AMBOS | S | PSI memory + frametime p99 | +| 3 | PERF | S | FPS texture-heavy | +| 4 | PERF | S | FPS + bandwidth GPU | +| 5 | PERF | S | estabilidade GPU | +| 6 | AMBOS | S | MemAvailable + decode ok | +| 7 | PERF | S | FPS sustentado | +| 8 | AMBOS | S | depende da divergência | +| 9 | PERF | A | load time ROMs | +| 10 | AMBOS | A | MemAvailable + frametime | +| 11 | PERF | A | FPS em PS1/PSP HW | +| 12 | FOOTPRINT | A | RSS daemons | +| 13 | PERF | A | freq sustentada | +| 14 | DECISÃO | A | — | +| 15 | PERF | B | input latency ms | +| 16 | AMBOS | B | RSS + crackle | +| 17 | FOOTPRINT | B | disk + cache | +| 18 | PERF | B | FPS per-game | +| 19 | AMBOS | B | boot time + RSS | +| 20 | PERF | B | CPU em vídeo | + +--- + +# Ordem recomendada de execução + +| Fase | Itens | Duração estimada | +|------|-------|------------------| +| **Pré-req obrigatório** | 0, 1 | 3–5 dias | +| **Quick wins RAM/DDR/CMA** | 2, 3, 6 | 2 dias | +| **Stack gráfico** | 4, 5 | 1–2 dias | +| **DT archeology** | 8 | 2–3 dias | +| **Compilação tunada** | 7 | 1 dia + build time | +| **Polimento stack** | 9, 10, 11, 12, 13 | 3 dias | +| **Decisão Vulkan** | 14 | 1 dia | +| **Latência e áudio** | 15, 16 | 1 dia | +| **QoL e economia** | 17, 18, 19, 20 | 2 dias | +| **Documentação** | 21 | paralelo | +| **CI** | 22 | longo prazo | + +**Total estimado:** ~3–4 semanas focadas + build time. + +--- + +# Itens explicitamente DESCARTADOS (e por quê) + +- ~~big.LITTLE / EAS~~ — RK3326 é 4× A35 homogêneos. +- ~~Transparent HugePages~~ — fragmenta em 1GB. Manter `never`. +- ~~CPU isolation (`isolcpus`, `nohz_full`)~~ — 4 cores é pouco. +- ~~PGO em Dolphin/PCSX2/RPCS3~~ — não rodam com perf útil no A35. +- ~~F2FS~~ — ext4 mais seguro em microSD variável. +- ~~Swap em microSD~~ — destrói cartão. +- ~~`-O3` universal~~ — icache apertado; pontual após bench. +- ~~`mitigations=off`~~ — ganho marginal em A35, risco ruim. + +--- + +# Quando revisitar este TODO + +- Após itens 0 e 1: reprioritizar com dados. +- A cada release do Mesa: PanVK em G31 saiu de experimental? +- A cada release do kernel: patches novos de Panfrost/rockchip? +- Se o projeto ganhar contribuidores: quebrar em issues granulares. \ No newline at end of file