lardon3d/docs/performance/target_hardware.md
fy59 b84f860d86 refactor(core): freeze global maintenance baseline
Complete the A-to-Z Lardon3D maintenance and coherence pass.

Generalize host resource policy, remove the global CPU12 ceiling, preserve
host CPU/RAM reserves, scale Task capabilities through the Resource Governor,
and validate deterministic parallel GV execution.

Migrate Project DB to v23 with data-driven camera, lens, optical configuration
and calibration profiles, including manual lenses without EXIF.

Integrate safe optional LARDON SSD swap/scratch control with Governor and F10
drain/safe-to-unplug semantics.

Refactor the ncurses TUI into a runtime observatory with durable progress,
elapsed time, smoothed ETA, throughput, resource telemetry, Governor state,
optics workflow, colors and compact/no-color fallbacks.

Reconcile Queue lifetime, persistence, concurrency, comments, tests,
README, AGENTS and canonical documentation.

GLOBAL_MAINTENANCE_AUDIT=PASS/FROZEN
2026-09-01 08:00:47 +02:00

186 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Profil de performance de l'hôte de validation
Ce document décrit une politique de performance mesurée. Il ne modifie aucun
contrat de correction du Matcher, du Match Store ou du Match Result.
## Hôte principal de validation
Ce profil est une preuve de performance et de stabilité pour la politique
portable. Il ne constitue ni une identité produit, ni une exigence matérielle,
ni un plafond CPU/GPU applicable aux autres hôtes.
- AMD Ryzen 7 8845HS, Zen 4, 8 cœurs et 16 threads SMT ;
- Radeon 780M à mémoire système partagée ;
- 16 Gio de RAM et zram d'environ 6 Gio ;
- Arch Linux, Clang 22, OpenCV 5.0.0.
Le build OpenCV observé emploie TBB 2023.1, expose 16 threads par défaut et les
chemins SIMD jusqu'à AVX512-SKX. Il a été compilé avec OpenCL, mais
`cv::ocl::haveOpenCL()` retourne faux. Vulkan énumère en revanche
`AMD Radeon 780M Graphics (RADV PHOENIX)`, API 1.4.354, avec une file compute
dédiée et de la mémoire UMA host-visible/cohérente.
Le sysfs amdgpu de cet hôte expose 512 Mio dans `mem_info_vram_total` et
7 986 020 352 octets dans `mem_info_gtt_total`. Le profil matériel conserve les
512 Mio comme capacité de payload observable, mais la combinaison petit
aperture/GTT à l'échelle de la RAM suffit à classer ce GPU shared/UMA sans
hardcoder son device ID. Le Governor débite alors les ressources GPU exactement
une fois de `MemAvailable` et n'utilise jamais cet aperture comme mémoire libre
séparée pour contourner la réserve dure de 3 Gio et la zone de prudence jusqu'à
4 Gio.
Le runtime actuel de Lardon3D possède un worker lourd. Le profil interactif
établit au démarrage une baseline OpenCV depuis le compute-pool réellement
disponible. Sur cet hôte précis, le Governor réserve quatre threads logiques au
desktop et en admet douze ; douze est une observation matérielle, pas un plafond
produit. Pour chaque séquence, l'unique callback Queue applique temporairement
le compte CPU immuable admis dans `1..compute-pool`, le vérifie et
restaure la baseline sur toute sortie. `cv::setNumThreads()` reste une
configuration process-wide : sa mutation concurrente par plusieurs workers
n'est pas supportée. Un futur pool multi-worker devrait donc changer ce modèle
explicitement, pas multiplier silencieusement ces mutations globales.
Sur cette machine mesurée, le worker Queue applique à lui-même le compute-pool
`0-5,8-13`, tandis que le
creator/main reste unrestricted `0-15`. Certains helpers de cache disque Mesa
observés avaient réélargi leur affinité après l'initialisation lazy. Comme un
pidfd ne stabilise pas le TID numérique pour `sched_setaffinity(tid)`, Lardon3D
ne tente aucune mutation auxiliaire. Il établit plutôt
`MESA_SHADER_CACHE_DISABLE=true` avant toute création de pthread applicatif et
toute initialisation Vulkan. Une absence prend ce défaut sûr ; les valeurs
explicites exactes `true`/`1` sont respectées, tandis qu'une valeur explicite
fausse ou malformée reste inchangée mais interdit le démarrage. Sur la 780M
validée, les helpers `*:disk$0` sont absents et tous les threads runtime vivants
observés gardent `0-5,8-13`. Cette politique est opérationnelle et inoffensive
hors Mesa ; elle n'ajoute ni identité scientifique, ni état durable, ni sweep
post-init.
Le backend public ne suppose pas que tout consumer traverse ce démarrage : sa
première requête Vulkan non vide vérifie `true`/`1` sans modifier
l'environnement, avant tout appel Mesa. Une valeur absente ou différente
retourne `UNAVAILABLE`, mémorise l'indisponibilité et ne produit aucune sortie.
Les benchmarks et la feasibility autonomes établissent le défaut sûr comme
première action de `main` ; les lectures metadata restent non initialisantes.
Les anciennes mesures exploratoires montrent que quatre Matchers à quatre
threads favorisent SIFT et les cas 4096, tandis que deux à huit favorisent ORB
8192. Elles n'établissent pas un pool de production actuel. Tout futur modèle
devrait être choisi par le Governor à partir de la classe de charge et prouver
un contrôle de concurrence compatible avec la configuration globale OpenCV.
Quatre Matchers avec un ou deux threads chacun dégradent fortement les grands
cas ORB. Quatre fois quatre threads augmente le working set et la variance, mais
peut améliorer SIFT soutenu. Le Governor devra compter les threads OpenCV dans
le budget CPU afin d'éviter `workers × threads` supérieur aux 16 threads
matériels.
Le working set directement contrôlé d'un Matcher SIFT/RootSIFT reste inférieur
à environ 10 Mio, hors scratch TBB/OpenCV. Même plusieurs Matchers restent loin
de la pression mémoire sur 16 Gio ; les mesures n'ont produit aucun swap-in ni
swap-out. La limite pratique observée est le CPU, pas la RAM.
## Fallback portable
Le build portable conserve les réglages Meson génériques et ne force ni
`-march=native`, ni OpenCL, ni un nombre de threads spécifique au 8845HS. Sur une
autre machine, laisser OpenCV choisir son backend et limiter l'orchestration à
un Matcher reste le fallback sûr. Une future configuration multi-worker devra
être dérivée du profil matériel par le Resource Governor, sans second scheduler.
## Méthode et portée
`benchmark-matcher` utilise des Feature Sets synthétiques persistés, un warm-up
et sept répétitions dont il rapporte la médiane. Les mesures absolues sont
locales et sensibles au boost et à la température ; la décision repose surtout
sur le scaling et le débit soutenu. La campagne a été exécutée avec le governor
Linux `powersave`; après charge soutenue, 6172 °C ont été observés et aucun
swap-in/swap-out. Le coût dominant reste l'évaluation exacte des distances dans
`cv::BFMatcher::knnMatch`.
Le backend Vulkan ORB de production est borné, utilise une invocation par query
et ne matérialise aucune matrice A×B. Sur la 780M, le workgroup 32 est le meilleur
des quatre candidats 32/64/128/256 à 4096 et 8192. Le chemin complet warm mesure
environ 0,18 ms à 256, 0,45 ms à 1024, 1,6 ms à 4096 et 4,0 ms à 8192, contre
environ 0,10, 0,96, 14,7 et 59,6 ms pour BFMatcher CPU lors de la campagne
production. L'initialisation lazy mesurée vaut environ 129136 ms. Le seuil
`feature_count_a × feature_count_b >= 768²` évite le GPU pour les petits travaux.
La mémoire directement contrôlée vaut 640 Kio par slot. Rolling AUTO normal
réserve exactement un slot ; seule la couture privée de sûreté/benchmark peut
réserver deux slots, soit au plus 1,25 Mio, débités une fois de la RAM sur la
780M UMA. Le backend mappe exactement cette capacité pendant la séquence et
rend le second slot avant une admission depth 1 suivante. Les tests de parité
couvrent exactement le top-2 jusqu'à 8192, le Match File complet et le fallback
CPU. Ces nombres décrivent la machine mesurée et ne sont pas un contrat portable
de latence.
Le run S21 AUTO final sur cette cible mesure 172 741 résultats durables en
2 345,444485079 s, soit 73,649/s. Sur les échantillons connus, GPU busy vaut
26 % en moyenne, 27 % en médiane et 36 % au maximum; l'utilisation moyenne
connue du compute-pool vaut 9,68 % de ses 12 CPU logiques. Le RSS observé
culmine à 168 980 480 octets et le HWM à 250 658 816 octets. Le minimum
`MemAvailable` reste 10 927 390 720 octets, PSI mémoire maximal et deltas swap
restent nuls. Après le run, Sway répond, Firefox et son flux PipeWire vers le
casque actif restent présents; PSI mémoire avg10/60/300 est nul. Ces signaux
objectifs attestent la conservation du desktop, sans prétendre mesurer une
perception subjective.
## Geometric Verifier Fundamental — Gate A
Le 9 août 2026, `benchmark-geometric-verifier` a comparé FM_RANSAC, USAC_DEFAULT, USAC_MAGSAC,
USAC_ACCURATE et MAGSAC à seed locale sur le Ryzen 7 8845HS, OpenCV 5.0.0 et Clang 22.1.8. Sur
8192 correspondances, 70 % d'outliers et bruit 0,75 px, le candidat local mesure
10,80/11,04/11,35 ms médiane/p95/pire. FM_RANSAC mesure 316,44/318,87/319,66 ms avec seulement
0,413 de recall.
Avant campagne, PSI CPU/mémoire/I/O avg10 était nul, `MemAvailable` environ 9,72 Gio et
`pswpin/pswpout` nul. Après 30,4 s à environ 99 % d'un CPU, PSI et swap restaient nuls,
`MemAvailable` environ 9,74 Gio et le capteur CPU observé passait d'environ 54,6 à 55 °C. Ce sont
des proxies objectifs, pas une mesure subjective de fluidité.
Le coût court et le faible working set rendent Vulkan `NOT_JUSTIFIED` pour ce verifier sur la
Radeon 780M. Le GPU reste utilisé uniquement par le Matcher ORB existant.
La validation scientifique initiale réservait un CPU logique, 4 Mio et un
worker, avec lots 1/2/4/8. Un run de la vraie Task sur 1000 parents, suivi de
ses chemins de reprise/configuration, a traversé environ
2001 parents réutilisés en 5,870 s (environ 341/s). Ce chiffre inclut DB, checkpoints et fixture ;
il ne remplace pas la latence estimator-only Gate A. Le processus de test a culminé à 25 964 Kio
RSS. `MemAvailable` a varié de 10 702 988 à 10 692 916 Kio, sans swap ; PSI avg10 final était
0,34 % CPU et 0 % mémoire/I/O. Les latences médiane/p95 par parent et le RSS début/fin n'étaient
pas mesurables avec ce harness et ne sont donc pas extrapolés.
La maintenance ultérieure a conservé les octets GVR et l'USAC interne sériel,
mais parallélisé les parents indépendants sous un callback propriétaire. Sur le
fixture réel de 4113 parents, CPU1/2/4/8/12 donnent respectivement
60,7514/83,9556/104,7545/116,6329/119,7606 parents/s, avec digest littéral
identique. La capacité sûre est 16 participants et 16 parents par lot ; la
politique utile s'arrête à CPU8, car CPU12 n'ajoute que 2,68 %. Ces chiffres
restent une preuve locale, pas une identité ni un optimum portable.
## Feasibility Vulkan SIFT / RootSIFT
Sur le même RADV PHOENIX, `shaderFloat64`, les timestamps compute, un subgroup
de 64 lanes et les workgroups jusqu'à 1024 invocations sont disponibles. La
meilleure variante SIFT FP32 utilise 64 lanes. Après fermeture d'une lecture
vidéo et retour à un PSI avg10 nul, cinq campagnes donnent à 8192² : SIFT
115,030 ms CPU contre 75,243 ms total potentiel (1,53×), et RootSIFT
117,484 ms contre 74,744 ms (1,57×). À 4096², les gains totaux tombent à 1,14×
et 1,11×. Les quatre paires asymétriques testées perdent face au CPU. FP64
atteint environ 271 ms à 8192².
La campagne numérique trouve une divergence top-2 sur des sommes égales
adversariales pour FP32 comme FP64. Sur 24 160 requêtes SIFT et 24 161 requêtes
RootSIFT, elle compte respectivement une divergence d'index, 20 251 divergences
de bits de distance et zéro divergence Lowe, puis une divergence d'index,
20 824 divergences de bits et zéro divergence Lowe. Le backend devrait donc porter
une identité scientifique propre et ne pourrait pas employer le fallback CPU
transparent d'ORB. Cette complexité n'est pas justifiée par le profil de
performance : SIFT et RootSIFT Vulkan sont rejetés pour Lardon3D v1 sur cette
cible, OpenCV reste la référence production.
Un run soutenu de 5000 dispatchs mixtes 1024/4096/8192/4096 a traité environ
1232 paires/s en 4,06 s. Le processus de benchmark complet a culminé à environ
202 Mio RSS ; les compteurs `pswpin` et `pswpout` sont restés à zéro. Après le
run, PSI CPU `some avg10` valait 0,14 %, PSI mémoire et I/O 0 %, avec 76 °C CPU
et 64 °C au bord GPU. Ces mesures sont des observations ponctuelles, pas des
seuils du Resource Governor.