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) <noreply@anthropic.com>
28 KiB
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
# 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:
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ÃOdebugoptimized, NÃOdebug)-Db_ndebug=true(asserts off)-Db_lto=true(opcional, recomendado)
Variáveis de ambiente que jamais podem estar setadas em produção:
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% FPStrace→ captura de cada draw callnocrc→ 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:
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
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(ouRelWithDebInfocom debug em pkg separado)- Nunca
Debug - Binário
stripped
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
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.mdcom 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:
# 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.
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:
dmesg -w > dmesg-during-bench.log &
# Filtrar: oom, kswapd, pagealloc, reclaim, compact_fail
Contadores de sistema:
vmstat 1 60 > vmstat.log
# si/so (swap in/out), wa (iowait), st (stolen), free, buff, cache
Frequências CPU/GPU/DDR + temperatura:
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 <kernel-src> 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 <rom> |
bios_sha256 |
sha256sum <bios> |
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-<distro>-<cenario>-<path>/
│ ├── 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:
- Carrega
summary.jsonde N runs - Agrupa por
(distro, cenario, core_path) - Emite pivot com medianas + IQR
- Flagga runs com alta variância (σ/μ > 10%) para re-rodar
- Gera gráficos de frametime density + PSI timeline
Critério: ./bench.sh <cenario> <distro> 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:
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.
- Desabilitar zswap (intercepta antes do zram).
zswap.enabled=0na cmdline. - Priority 100 no swapon.
- Proibido swap em microSD.
# /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:
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_ondemandcom upthreshold ~40% OUperformancevia 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.
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:
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:
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.
Validação: estabilidade em suspend/resume; ausência de GPU hangs. Perf pode não mudar — foco é correção.
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
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
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,cmaglobal — 64–128MB comum; 256MB é exagero em 1GBrockchip,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
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
CmaFreefica 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=64Mou 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:
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
-O3universal. L1I 32KB, L2 256KB;-O3infla binário e pressiona cache. Pontual após bench. - Não
-mcpu=cortex-a35em libs genéricas (quebra portabilidade). -fltoem: mesa, retroarch, cores libretro, sdl2, ffmpeg, zlib-ng.
Pacotes para recompilar:
- mesa (item 4)
- retroarch
- Cores libretro em uso
- sdl2
- ffmpeg com
--enable-neon --cpu=cortex-a35 - zlib-ng (substitui zlib, 10–30% em descompressão de ROMs zipadas)
- 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:
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-mapsregulator-*→ min/max-microvolt (margem de undervolt)rockchip,pwm-regulatorreserved-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%.
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:
1xem ≤480p,1.5xem 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.
systemd-analyze blame > /tmp/blame-nosso.txt
systemctl list-units --state=running --type=service
Alvos:
ModemManager,cups,packagekit,tracker-*,geoclue,fwupd→ maskavahi-daemon,bluetooth, WiFi → socket-activate
Journal em RAM:
# /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.
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:
performanceem gameplay via pre-launch hook;schedutilem idle.- Comparar trips com dArkOS/ROCKNIX.
- Undervolt via
cpu-supplyno 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=1sob demanda, documentar risco. - C (Zink pontual): OpenGL sobre Vulkan, raramente ganha em G31.
Investigar o que dArkOS/ROCKNIX fazem:
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.
zcat /proc/config.gz | grep CONFIG_HZ=
cat /proc/bus/input/devices
RetroArch:
video_frame_delay— testar 0–4 per-corevideo_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.
# /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.
# /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]
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 distrosservice-audit.md— daemons ativos por distrocflags-audit.md— flags por distromesa-version.mdkernel-version.mdvulkan-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. Manternever.CPU isolation (— 4 cores é pouco.isolcpus,nohz_full)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.— icache apertado; pontual após bench.-O3universal— ganho marginal em A35, risco ruim.mitigations=off
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.