IOS LLE: checkpoint NAND conformance and diagnostic tooling
Preserve formatted NAND boot and Wii Remote pairing, add DMA/SRAM conformance tests and a Wii comparison probe. Keep P1 profiling tools and native update A/B evidence; reject the unhelpful targeted SRAM shortcut.
This commit is contained in:
1 parent
b931671fde
commit
c230971f07
64 files changed
+6488
-238
No files matched your search
@@ -30,6 +30,15 @@ CPUThread = True
|
||||
WiiIOSLLEDumpPath = C:/absolute/path/to/dumps
|
||||
```
|
||||
|
||||
Detailed JIT memory profiling is optional and disabled by default. To collect slow-access
|
||||
regions, SRAM page counts and sampled hot addresses, set `WiiStarletJITMemoryProfiling = True`
|
||||
under `[Core]` before starting emulation. The launch script exposes the same choice through
|
||||
`-ProfileJitMemory` and explicitly disables it when that switch is absent. Aggregate slow-read,
|
||||
slow-write and instruction counters remain active in both modes. A log field of
|
||||
`memory-profile=false` means the detailed region counts are unavailable, not that there were no
|
||||
accesses. The setting is fixed for the core's lifetime and does not alter guest memory, timing,
|
||||
interrupts, or NAND persistence. It is host instrumentation and is not serialized in savestates.
|
||||
|
||||
The selected directory must contain the three matching files from one console:
|
||||
|
||||
| File | Exact size | Purpose |
|
||||
@@ -105,6 +114,29 @@ X2 and immediately submit the next request with X1 before Starlet is scheduled a
|
||||
|
||||
## Implemented hardware
|
||||
|
||||
### Freshly formatted NAND and controller pairing
|
||||
|
||||
Automatic Wii Remote pairing is optional at startup when `/shared2/sys/SYSCONF` or
|
||||
its `BT.DINF` entry is absent. This permits boot0/BootMii to run after a formatter
|
||||
without the host creating configuration files or restoring data from an older
|
||||
SFFS superblock. Native Wii software remains responsible for initializing its NAND;
|
||||
the emulated remotes use their default identities until pairing is established.
|
||||
Existing pairing records are still reused or populated as before. Unreadable NAND,
|
||||
malformed directories/configuration and failed journal writes remain errors.
|
||||
This removes a host-side startup blocker; it does not guarantee that the formatter
|
||||
installed a complete, bootable Wii system.
|
||||
|
||||
When native first-boot setup creates a new SYSCONF after formatting, a full Dolphin
|
||||
restart lets the existing startup pairing routine populate its empty BT.DINF.
|
||||
The write must use the native SFFS authentication layout: the complete 20-byte HMAC
|
||||
starts at spare byte 1 of cluster page 6, with a second copy split between page 6
|
||||
bytes 21-32 and page 7 bytes 1-8. Bad-block markers and unrelated spare bytes are
|
||||
preserved, and ECC is regenerated for the ciphertext. The pairing regression test
|
||||
checks both HMAC copies and spare/ECC preservation; valid decryption alone does not
|
||||
prove IOS will accept the modified file.
|
||||
|
||||
### Devices and execution
|
||||
|
||||
- ARM and Thumb instruction interpretation needed by the observed boot, including banked CPU
|
||||
modes, user-bank block transfers, SPSRs, high Starlet exception vectors, IRQ/FIQ entry,
|
||||
ARM/Thumb interworking, ARMv5TE branches/multiplies, and CP15 registers.
|
||||
@@ -506,6 +538,19 @@ frequency, guest scheduling/idle detection and device-access cost.
|
||||
| Configuration | `Core/Config/MainSettings.{h,cpp}` |
|
||||
| Starlet CPU/device unit tests | `UnitTests/Core/IOS/Starlet/ARMCoreTest.cpp` |
|
||||
|
||||
## Conformance work
|
||||
|
||||
The current priority is behavioral agreement with a real Wii, not a fixed FPS
|
||||
target. [`Tools/WiiConformanceProbe`](../Tools/WiiConformanceProbe/README.md)
|
||||
builds one PPC homebrew binary to run against native IOS on both systems and
|
||||
compares numbered return codes and outputs. Keep the probe binary identical,
|
||||
record the IOS revision and starting NAND state, and label physical-Wii versus
|
||||
emulator captures explicitly. Local captures are not automatically treated as
|
||||
hardware ground truth. When a result differs, add a minimal deterministic unit
|
||||
test for the relevant IPC, memory, timing, or device behavior before changing
|
||||
the emulator. Performance optimizations must preserve those observations and
|
||||
the BootMii → Wii boot path.
|
||||
|
||||
## Safe development rules
|
||||
|
||||
1. Treat all dumps as private console material and never print keys or ROM/NAND bytes in logs.
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
# Protocole P1 — attribuer les ralentissements Wii LLE
|
||||
|
||||
Date : 19 septembre 2026. Statut au 22 septembre : **capture noyau locale validée ;
|
||||
coût du collecteur, cas PPC et chemin critique Wii non qualifiés**.
|
||||
Aucune nouvelle mise à jour n'est lancée par la rédaction de ce document.
|
||||
Il remplace la stratégie « modifier, refaire une mise à jour, comparer les FPS ».
|
||||
|
||||
## 1. Question et règle de décision
|
||||
|
||||
Sur les passages réellement lents, déterminer **quel travail ou quelle attente retarde
|
||||
la progression de l'émulation**, dans quelles fonctions, et pour combien de temps.
|
||||
Le résultat attendu n'est pas « un cœur à 100 % », mais une attribution vérifiable.
|
||||
|
||||
Une seule exécution de diagnostic est prévue après qualification du dispositif.
|
||||
Aucun nouveau correctif de performance avant un rapport d'attribution exploitable.
|
||||
Une capture incomplète ne justifie pas un correctif au hasard : on répare le dispositif,
|
||||
et on précise quelle information manque avant d'envisager une capture complémentaire.
|
||||
Une seule cause est ensuite traitée ; la validation porte d'abord sur sa charge locale.
|
||||
|
||||
## 2. Pourquoi A–F ne suffisent pas
|
||||
|
||||
- Les instantanés espacés d'environ 10 secondes ne décrivent ni les pics ni leurs piles.
|
||||
- Les FPS échantillonnés ne sont pas une distribution des temps de frame.
|
||||
- Un nombre d'accès mémoire ou d'instructions JIT ne mesure pas leur coût CPU.
|
||||
- `ARMCore::RunCycles` contient également `m_bus.AdvanceCycles` : son temps inclusif
|
||||
ne doit pas être présenté intégralement comme du calcul ARM.
|
||||
- `AdvanceCycles` appelle les périphériques, dont OHCI et le réseau : additionner
|
||||
ces temps imbriqués compterait plusieurs fois le même travail.
|
||||
- `Sampler.cpp` utilise `SuspendThread`/`ResumeThread` ; ses observations historiques
|
||||
ne deviennent pas une référence de temps sans perturbation.
|
||||
- Le lecteur F ne résout pas certaines adresses JIT. Une annotation absente n'est
|
||||
ni zéro travail JIT ni une preuve que tous les autres offsets sont incorrects.
|
||||
- Les 600–2 700 Mo de journal sont des repères approchés, pas une charge identique.
|
||||
- La durée entre messages utilisateur n'est pas la durée exacte de la mise à jour.
|
||||
- Les conditions hôte/serveur diffèrent. F est observé plus lent que E, mais la cause
|
||||
n'est pas isolée. Répéter simplement F avec un autre réglage ne résout pas cela.
|
||||
|
||||
## 3. Geler le scénario, sans toucher aux NAND existantes
|
||||
|
||||
Le diagnostic concerne le ralentissement actuel : source actuelle figée correspondant
|
||||
au comportement F, profilage détaillé des accès désactivé, **sans nouvelle optimisation**.
|
||||
Créer une build de diagnostic propre, non incrémentale, et ne pas remplacer les builds
|
||||
figées D/E/F. Conserver le patch et les empreintes des sources, y compris les fichiers
|
||||
non suivis utilisés, options de compilation, compilateur, EXE, PDB et paramètres.
|
||||
Vérifier l'identité EXE/PDB ; cela ne suffit pas, à elle seule, à valider un lecteur de types.
|
||||
|
||||
Utiliser un nouveau profil depuis la graine pré-mise à jour déjà vérifiée :
|
||||
SHA256 `07b2f4bc543cfd4203efc448538505e9d503b2727c16aaff8d8c0b286d8b4f0c`.
|
||||
Conserver les mêmes réglages Wii, réseau NAT, rendu, vitesse 100 %, horloges invitées,
|
||||
SD et persistance. Noter les différences de chemins et rien d'autre.
|
||||
Un démarrage du processus n'implique pas un cache disque Windows froid ; ne pas vider
|
||||
les caches système, changer l'affinité ou désactiver l'antivirus pour fabriquer un résultat.
|
||||
|
||||
Relever au départ et pendant la capture : charge des autres processus, CPU logique utilisé,
|
||||
état d'alimentation, fréquence disponible, mémoire/pression de pagination, disque et GPU.
|
||||
Ne pas lancer de compilation, benchmark, hachage massif, nettoyage ou autre test en parallèle.
|
||||
Ne pas fermer des applications utilisateur sans accord. Si un concurrent perturbe une fenêtre,
|
||||
la signaler et mesurer sa contribution plutôt que l'effacer du rapport.
|
||||
|
||||
## 4. Deux couches de mesure sur la même horloge
|
||||
|
||||
### A. Profil système Windows, indépendant des layouts C++
|
||||
|
||||
WPR, Xperf et WPA sont présents sur cette machine ; `wpr -profiles` a été vérifié.
|
||||
Employer un profil ETW ciblé, validé avant le test :
|
||||
|
||||
- CPU échantillonné avec piles, cible initiale 1 ms, intervalle réellement utilisé consigné ;
|
||||
- changements de contexte et réveils, pour séparer **Running / Ready / Waiting** par thread ;
|
||||
- chargement des modules, événements disque/fichiers, fautes matérielles de pagination ;
|
||||
- métadonnées d'activité réseau, sans contenu des paquets ;
|
||||
- fréquence/puissance si disponibles. Une donnée absente reste « indisponible ».
|
||||
|
||||
Les vues CPU échantillonné et CPU précis répondent à des questions différentes : localisation
|
||||
du calcul d'une part, ordonnancement/attentes d'autre part. Les combiner, sans confondre une
|
||||
pile d'attente avec une preuve d'attente disque. [Documentation Microsoft](https://learn.microsoft.com/en-us/troubleshoot/windows-server/support-tools/support-tools-xperf-wpa-wpr)
|
||||
|
||||
Ne plus utiliser de suspension de thread ou d'attachement au débogueur pour chronométrer.
|
||||
Pas de profilage heap complet, trace de chaque accès mémoire, ni capture de paquets par défaut.
|
||||
Filtrer l'analyse sur le PID/TID exact et conserver les processus concurrents pour expliquer
|
||||
le temps Ready. Ne pas supposer que le PID suffit après un redémarrage : enregistrer sa date
|
||||
de création. Aucun arrêt/annulation d'une session ETW tierce ; vérifier les sessions avant démarrage.
|
||||
|
||||
### B. Télémétrie native légère, versionnée
|
||||
|
||||
Publier les compteurs depuis le code qui les possède ; ne plus les déduire d'offsets PDB
|
||||
via `ReadProcessMemory`. Un schéma versionné comporte `run_id`, version, QPC/fréquence,
|
||||
PID/TID, génération du cœur/rechargement IOS et des compteurs monotones.
|
||||
L'export asynchrone est borné ; les débordements sont comptés. Aucune écriture de log
|
||||
synchrone à chaque instruction ou accès. Ne pas ajouter de verrou partagé au chemin mémoire.
|
||||
Récupérer les données sur leur thread propriétaire, sans lecture C++ concurrente non synchronisée.
|
||||
|
||||
- Temps invité écoulé et cycles ARM/PPC, séparés du temps hôte QPC.
|
||||
- Temps de frames réellement produites : histogramme p50/p95/p99 et longues frames,
|
||||
rapporté au mode vidéo du profil (50 ou 60 Hz). Une médiane de FPS n'est pas ce calcul.
|
||||
- Agrégats toutes les secondes ; chronologie d'analyse en fenêtres de 250 ms quand
|
||||
les événements le permettent. Marquer les fenêtres qui n'ont pas assez de données.
|
||||
- JIT : compilations, invalidations, instructions natives/fallback, accès lents existants,
|
||||
entrées en attente et sorties de slice, avec identifiant de génération après reset.
|
||||
- NAND : lectures/programmes/effacements, transactions, octets et erreurs ; séparer
|
||||
sérialisation/hash, appels d'écriture, `IOFile::Flush` et attente hôte observée.
|
||||
- Réseau : octets/trames hôte reçus, mise en file NAT, remise USB à IOS, occupation maximale
|
||||
et âge des files. Le débit reçu ne prouve pas le débit consommé par IOS.
|
||||
|
||||
Les chronomètres de régions fréquentes sont échantillonnés et calibrés, jamais posés sur
|
||||
chaque accès ARM. Les frontières plus rares (rechargement, compilations, gros transferts)
|
||||
peuvent produire des événements. Éviter un échantillonnage périodique aligné sur la boucle
|
||||
invitée ; conserver le taux de sélection et distinguer estimation et total exact.
|
||||
|
||||
### C. Rendre les échantillons JIT attribuables
|
||||
|
||||
Un PDB décrit le C++ compilé, pas automatiquement le code généré à l'exécution.
|
||||
Exporter, à compilation/invalidation, les intervalles d'adresses **hôte** du JIT ARM et
|
||||
du JIT PPC, dispatcher/trampolines compris, avec QPC et génération ; pour les blocs,
|
||||
indiquer PC invité, ARM/Thumb et identité du mapping. Ne pas extraire ni publier le firmware.
|
||||
Une adresse réutilisée après vidage du cache doit se résoudre selon la date de l'échantillon.
|
||||
|
||||
Classer l'IP feuille même si la pile ne traverse pas correctement une transition JIT/C++.
|
||||
Ne pas inventer de parent de pile manquant. Garder « pile tronquée » et « code non attribué »
|
||||
visibles ; ajouter une instrumentation ciblée si ces trous empêchent la décision.
|
||||
Le support `Common::JitRegister` existant côté PPC est un point d'intégration à examiner,
|
||||
pas une garantie que le JIT ARM ou l'unwinding Windows sont déjà couverts.
|
||||
|
||||
## 5. Points d'attribution dans ce dépôt
|
||||
|
||||
| Domaine | Points à observer | Preuve recherchée |
|
||||
|---|---|---|
|
||||
| Ordonnancement ARM | `Starlet::RunSlice`, `ARMCore::RunCycles` | Coût de dispatch, quanta/s, transitions, temps invité/hôte |
|
||||
| JIT ARM | `ARMJitX64::Run`, compilation, code généré, helpers | Part CPU feuille, blocs invités chauds, recompilations |
|
||||
| Mémoire ARM | `ReadMemorySlow`, `WriteMemorySlow`, traduction, bus | CPU exclusif des helpers et classes d'accès, pas leur seul nombre |
|
||||
| Périphériques | `StarletMemory::AdvanceCycles`, DMA, AES/SHA, OHCI/EHCI | CPU exclusif par fonction ; attente simulée séparée du travail hôte |
|
||||
| NAND | `CommitNANDPages`, `NANDJournal::Append`, `IOFile::Flush` | CPU de préparation vs appels fichiers vs attente disque réelle |
|
||||
| Réseau | `SlirpNetwork::Poll`, AX88772, remise OHCI | CPU NAT/USB, files, progression hôte versus progression invitée |
|
||||
| PPC / rendu | JIT PPC, threads vidéo, présentation | Concurrence réelle et dépendances de l'émulation, pas seulement FPS |
|
||||
| Hors émulation | Limiteur, audio, logs, collecteur, Windows | Attente voulue, contention, CPU de diagnostic, temps Ready |
|
||||
|
||||
Sur un même thread, présenter les **temps exclusifs** des régions imbriquées.
|
||||
Présenter aussi leurs temps inclusifs, mais dans une autre colonne, non additionnable.
|
||||
Ne pas additionner le CPU de plusieurs threads comme une durée murale de mise à jour.
|
||||
Pour les attentes, suivre la dépendance qui retarde le thread utile ; un thread GPU qui
|
||||
attend l'émulation n'est pas une cause de ralentissement GPU.
|
||||
`fflush` n'est pas une preuve de vidage physique sur disque : le niveau de persistance
|
||||
actuel reste inchangé et les attentes sont établies par les événements hôte.
|
||||
|
||||
## 6. Qualification obligatoire, sans demander de mise à jour à l'utilisateur
|
||||
|
||||
Avant de dire « lance la mise à jour », un contrôle local court doit démontrer :
|
||||
|
||||
1. EXE/PDB identifiés ; compteur versionné lu correctement ; horloges alignées ; un reset
|
||||
ne produit pas de deltas négatifs ; pas de perte silencieuse d'événements.
|
||||
2. Une boucle JIT connue est correctement attribuée ARM/PPC ; son coût CPU augmente
|
||||
comme prévu. Un cas d'attente connu est classé Waiting, pas « calcul JIT ».
|
||||
3. Les scopes imbriqués d'un test ont des temps exclusifs cohérents, sans double comptage.
|
||||
4. Un cas de journal synthétique et de réseau local, sans service Nintendo, est visible.
|
||||
5. Mesurer le surcoût ON/OFF du dispositif complet sur la même charge locale, dans le même
|
||||
binaire et en ordre alterné. Budget initial : **2 %** de temps mural/CPU, bruit affiché.
|
||||
Ce seuil est une règle de projet, pas une garantie d'ETW. S'il est dépassé ou non résolu
|
||||
par le bruit, alléger les fournisseurs/samples avant le test. Le contrôle ne garantit
|
||||
pas le même surcoût sur toutes les phases natives : relever aussi la charge du collecteur.
|
||||
|
||||
Pas de nouveau comportement invité, pas de changement de NAT, timers, JIT, NAND ou SVC.
|
||||
Les boucles SVC/polling éventuelles sont d'abord attribuées à du CPU/PC invité ; aucune
|
||||
émulation accélérée d'appel IOS ne découle d'un simple comptage d'instructions.
|
||||
|
||||
## 7. Une capture native, puis analyse hors ligne
|
||||
|
||||
1. Vérifier réserve disque et absence de test/build actif. Enregistrer le manifeste.
|
||||
2. Armer ETW et la télémétrie **avant** de lancer le profil isolé ; confirmer une fenêtre
|
||||
visible et des mesures valides. Ne pas se baser sur les messages utilisateur pour armer.
|
||||
3. L'utilisateur lance une seule mise à jour. Garder 10 s de référence avant l'activité.
|
||||
Tout marquage manuel reste approximatif ; les phases sont reconstruites à partir des
|
||||
événements synchronisés, files réseau, travail invité et commits NAND.
|
||||
4. Téléchargement, calcul et installation peuvent se chevaucher : ne pas leur imposer
|
||||
trois phases exclusives artificielles. Une file vide ne prouve pas une attente serveur.
|
||||
5. Garder environ 10 s après la réussite signalée, puis arrêter uniquement la capture.
|
||||
Ne pas arrêter Dolphin, modifier la NAND ou cliquer à la place de l'utilisateur.
|
||||
6. Garde-fous initiaux : 15 min de capture, budget disque 4 Gio et réserve 5 Gio ; le pilote
|
||||
doit arrêter proprement **sa** capture si une limite approche, conserver le préfixe et
|
||||
déclarer les phases manquantes. Une trace incomplète n'est pas un échec de la mise à jour.
|
||||
7. Vérifier les événements perdus et le coût du profilage. Ne pas charger WPA ni effectuer
|
||||
une grosse analyse/hachage pendant la mesure. Fermer ensuite Dolphin avec l'utilisateur
|
||||
pour les vérifications NAND, comme pour F.
|
||||
|
||||
Les traces en mode fichier sont adaptées à ce scénario contrôlé, mais ajoutent des E/S :
|
||||
les distinguer du journal NAND, relever le volume et ne pas supposer leur coût nul.
|
||||
Les pertes d'événements rendent certaines conclusions impossibles ; les vérifier explicitement.
|
||||
[Sessions ETW/WPR — Microsoft](https://learn.microsoft.com/en-us/windows-hardware/test/wpt/sessions)
|
||||
|
||||
## 8. Rapport exigé avant tout correctif
|
||||
|
||||
Analyser la capture entière et, au minimum, trois fenêtres lentes non chevauchantes de
|
||||
10 s si elles existent, ainsi qu'une fenêtre rapide de la même exécution. Une fenêtre lente
|
||||
est définie avant analyse : vitesse invitée moyenne < 90 % pendant au moins 2 s ; analyser
|
||||
aussi les longues frames indépendamment. Rapporter l'absence de fenêtres admissibles.
|
||||
Comparer des types d'activité similaires ; ne pas comparer une pause réseau à une installation.
|
||||
|
||||
Livrer :
|
||||
|
||||
- Chronologie superposant vitesse/frames, CPU Running/Ready/Waiting, NAND et files réseau.
|
||||
- Top fonctions/piles, part CPU exclusive/inclusive, nombre d'échantillons, contexte invité.
|
||||
- Temps critique perdu en calcul, Ready et attentes expliquées ; catégories inconnues visibles.
|
||||
- Coût par unité de travail quand disponible : CPU/transaction, CPU/Mio traité, compilations
|
||||
par instruction, etc. Un compteur n'a de sens que pour la même opération/sémantique.
|
||||
- Liste des observations qui réfutent les autres pistes ; distinguer preuve et hypothèse.
|
||||
|
||||
Gates de qualité initiaux : zéro perte sur les flux indispensables à l'intervalle analysé,
|
||||
au moins 95 % des échantillons CPU Dolphin attribués à un domaine, compteurs intègres et
|
||||
coût de collecte qualifié. Ce sont des critères d'analyse, non des promesses de précision.
|
||||
Une pile incomplète peut permettre de classer un domaine sans identifier sa cause interne :
|
||||
on ne valide alors pas un correctif visant une fonction non résolue. Pas de fausse certitude
|
||||
statistique obtenue en traitant des échantillons temporels corrélés comme des essais indépendants.
|
||||
|
||||
Un correctif est admissible seulement si :
|
||||
|
||||
1. La cause apparaît dans plusieurs fenêtres lentes avec une signature explicable.
|
||||
2. Sa part sur le chemin qui retarde l'émulation est chiffrée, avec son incertitude.
|
||||
3. Un cas local représentatif reproduit cette charge ou cette attente.
|
||||
4. Le gain global plausible est estimé avant modification. Par exemple, supprimer tout un
|
||||
poste responsable de 5 % du temps critique ne retire au mieux que 5 % de cette durée.
|
||||
5. Le correctif garde le comportement matériel et passe les tests ciblés/interpréteur.
|
||||
|
||||
Décision pratique : si le CPU est dans les helpers, travailler ces helpers ; s'il est
|
||||
dans le code invité, examiner les blocs et le travail IOS ; si Ready domine, étudier
|
||||
la contention hôte ; si les attentes d'E/S dominent, traiter leur dépendance réelle.
|
||||
Si les files NAT sont pleines mais peu consommées, ne pas accuser le serveur ; si elles
|
||||
sont vides, confirmer l'attente avec les échanges/états disponibles ou laisser la cause ouverte.
|
||||
Si aucun poste ne domine, le rapport le dit : on ne fabrique pas un unique responsable.
|
||||
|
||||
## 9. Validation minimale après diagnostic
|
||||
|
||||
D'abord une validation locale répétable du poste identifié, résultat invité exact et même
|
||||
charge. Puis une validation native ciblée du scénario corrigé, pas une série de réglages.
|
||||
La trace de diagnostic peut localiser une cause, mais son temps n'est pas automatiquement
|
||||
une référence équitable face à une build sans instrumentation. Pour revendiquer un gain
|
||||
global, conserver un dispositif équivalent et répéter seulement si la variabilité observée
|
||||
empêche la conclusion. Annoncer cette nécessité et sa raison, pas un nouveau test à l'aveugle.
|
||||
L'objectif est de réduire les essais utilisateur ; garantir à l'avance qu'un seul essai
|
||||
prouvera toute causalité serait trompeur.
|
||||
|
||||
## 10. Artefacts et limites
|
||||
|
||||
Conserver dans un nouveau répertoire local ignoré : manifeste, capture ETL, télémétrie
|
||||
versionnée, mapping JIT daté, coût de collecte, tableaux de fenêtres, piles chaudes,
|
||||
rapport des attentes, événements perdus et décision. Le rapport lisible va dans `docs`.
|
||||
Pas de clés NAND, mémoire brute invitée, mots de passe ou contenu réseau dans les exports.
|
||||
Les ETL peuvent contenir des chemins et noms de processus : conservation locale, pas de push.
|
||||
|
||||
État au 22 septembre 2026 : instrumentation opt-in `DOLPHIN_PERF_TRACE=1`, mapping
|
||||
temporel JIT ARM/PPC, scopes/counters versionnés, profil WPR ciblé, décodeur ETL et
|
||||
sonde locale ont été ajoutés. La build isolée passe et la sonde privée a validé
|
||||
13 contrôles locaux sur 13 sur deux captures, avec zéro perte d'événement.
|
||||
Sur deux paires alternées, la phase ARM avec trace privée dépasse la phase sans
|
||||
trace d'environ 1,7 % en moyenne, mais la dispersion est supérieure à cet écart.
|
||||
Le budget de 2 % n'est donc pas qualifié. Le démarrage/arrêt du logger privé
|
||||
ajoute environ 0,34 s à ces exécutions courtes ; ce coût ne mesure pas le
|
||||
surcoût du collecteur WPR pendant une mise à jour Wii.
|
||||
La session WPR ne démarrait pas dans le jeton Windows de cette tâche
|
||||
(`0xc5585011`, droit de profilage système absent). Une capture synthétique
|
||||
administrateur a depuis produit l'ETL `P1-local-004`, sans perte. L'analyse
|
||||
hors ligne, reproductible sous PowerShell 5.1, valide 9 427 échantillons CPU,
|
||||
694 context-switches, dix ancres QPC alignées à cinq ticks près, et le sommeil
|
||||
connu effectivement classé `Waiting`. Le PDB local résout les fonctions C++;
|
||||
le mapping temporel attribue les IP du JIT ARM. Les 112 événements Xperf
|
||||
invalides sont des métadonnées `ImageID` hors du PID cible. Voir
|
||||
[`Tools/PerformanceTrace/README.md`](../Tools/PerformanceTrace/README.md).
|
||||
Le lot WPR `P1-overhead-001` a terminé ses huit charges synthétiques sans perte
|
||||
ETW ; seul son calcul final a échoué faute de Python dans le PowerShell
|
||||
administrateur. Le calcul récupéré hors ligne donne quatre écarts ARM ON/OFF de
|
||||
+9,7 %, +25,0 %, -0,5 % et +1,0 %, tandis que les quatre bases OFF ont une
|
||||
étendue de 34,5 %. Cette variabilité interdit d'annoncer un coût fiable du
|
||||
collecteur ou de qualifier le seuil de 2 %. Le script vérifie maintenant Python
|
||||
avant toute capture et peut analyser un lot déjà enregistré avec `-AnalyzeOnly`.
|
||||
Les traces ON montrent en outre un indexeur C++ hôte (`cpptools.exe`) actif
|
||||
pendant chaque essai et des services Dell intermittents. Le profil a été allégé
|
||||
des piles `ReadyThread`, tout en conservant leurs événements ; sa nouvelle
|
||||
version n'est pas encore qualifiée par un lot ON/OFF stable.
|
||||
Le second lot avec ce profil (`P1-overhead-002`) a conservé zéro perte ETW mais
|
||||
36,5 % d'étendue entre bases OFF. L'analyse par processeur montre que la sonde
|
||||
rapide passe 78,7 % de ses échantillons sur les logiques 0–3 contre 28,9 % pour
|
||||
la sonde la plus lente ; les temps ARM correspondants sont 7,59 et 10,33 s.
|
||||
L'ETL identifie un i7-1255U hybride avec SMT sur 0–3. Le lanceur Wii fixait
|
||||
déjà Dolphin à ces processeurs, mais les sondes OFF/ON ne l'étaient pas.
|
||||
L'affinité a été ajoutée aux sondes et vérifiée localement (masque 15 observé).
|
||||
Quatre bases fixées gardent toutefois 8,3 % de dispersion ARM ; elles ne
|
||||
valident pas encore le seuil initial de 2 %. Il serait trompeur de demander un
|
||||
troisième lot administrateur sans résoudre cette variabilité résiduelle.
|
||||
Les événements natifs ne sont pas activés dans les profils utilisateur par défaut.
|
||||
Une build et une sonde locale réussies ne valident pas le budget de 2 % ni le
|
||||
comportement d'une mise à jour native. Le vérificateur local conserve
|
||||
`native_update_ready=false` tant que les gates PPC, chemin critique natif et
|
||||
coût du collecteur n'ont pas été validées.
|
||||
**Ne pas demander de nouvel essai utilisateur tant que ces gates ne passent pas.**
|
||||
@@ -0,0 +1,182 @@
|
||||
# Wii IOS LLE : première trace CPU native de mise à jour
|
||||
|
||||
Date : 2026-09-23 (Europe/Paris). Cible : atteindre à terme environ 60 FPS
|
||||
pendant une mise à jour système, sans raccourci HLE ni régression BootMii/HBC.
|
||||
Ce document rapporte une **mesure exploratoire**, pas un gain de performance.
|
||||
|
||||
## Périmètre et qualité
|
||||
|
||||
- NAND : copie isolée `.starlet_update_ab_20260913/P1-trace-002`, créée depuis
|
||||
le journal pré-mise-à-jour vérifié (31 fichiers, SHA du seed
|
||||
`07B2F4BC543CFD4203EFC448538505E9D503B2727C16AAFF8D8C0B286D8B4F0C`).
|
||||
`.starlet_user3` et les anciens essais A–F n'ont pas été modifiés.
|
||||
- Build diagnostic figée : `.starlet_update_ab_20260913/build-P1-trace-002` ;
|
||||
exécutable SHA-256 `D809E04E2E8E900DB06D3813A67805E66EADB2BB79924CB8E805CB724360EAD4`.
|
||||
- ETL source : `.starlet-profile/P1-native-update-001/capture.etl` (3,88 Gio),
|
||||
session WPR de 600 s. Le champ `EndUTC` du manifest inclut environ 100 s de
|
||||
fusion de la trace : ce n'est **pas** la fin de la collecte.
|
||||
- Analyse : `.starlet-profile/P1-native-update-001-update-window/`, Xperf limité
|
||||
à 2026-09-22 22:57:00–23:00:33 UTC. Les échantillons cibles couvrent en fait
|
||||
**114,15 s** seulement, jusqu'à l'arrêt de la collecte vers 22:58:52 UTC.
|
||||
Les premières écritures NAND de mise à jour sont observées vers 22:57:23 UTC.
|
||||
La fenêtre CPU comprend donc aussi environ 23 s avant cette première écriture.
|
||||
La fin de la mise à jour, confirmée par l'utilisateur, n'est donc pas profilée.
|
||||
- TDH : 780 781 événements natifs décodés, zéro perte de buffer/événement et
|
||||
zéro erreur de décodage. Fusion Xperf : 25 419 ancres QPC, erreur maximale
|
||||
cinq ticks (QPC 10 MHz), 128 329 échantillons CPU sur 18 threads, 549 607
|
||||
changements de contexte retenus, zéro événement cible invalide. Les 57
|
||||
événements Xperf invalides sont hors PID cible.
|
||||
- Le surcoût du collecteur WPR en mise à jour native n'est pas qualifié par le
|
||||
lot synthétique précédent ; ces FPS ne constituent pas un A/B sans trace.
|
||||
|
||||
## Observations dans la fenêtre CPU retenue
|
||||
|
||||
| Mesure | Valeur |
|
||||
| --- | ---: |
|
||||
| Images « produced », intervalle médian | 21,16 ms (≈47,3 FPS) |
|
||||
| Images « produced », p95 | 35,33 ms (≈28,3 FPS) |
|
||||
| Images « produced », p99 | 68,58 ms (≈14,6 FPS) |
|
||||
| Thread principal TID 28212 | 95 154 / 128 329 échantillons (74,2 %) |
|
||||
| Thread GPU TID 13804 | 16 125 / 128 329 (12,6 %) |
|
||||
| Thread audio TID 22388 | 5 095 / 128 329 (4,0 %) |
|
||||
| JIT ARM / JIT PPC, échantillons de feuilles | 27 817 / 16 450 |
|
||||
| Instructions ARM, delta de snapshots | 4 566 790 374 |
|
||||
| Instructions ARM JIT natives, delta | 4 522 113 258 |
|
||||
| Accès lents JIT lecture / écriture, deltas | 59 486 963 / 218 257 365 |
|
||||
| Fallbacks ARM, delta | 42 433 964 |
|
||||
|
||||
Les symboles hôte les plus visibles sur le thread principal comprennent
|
||||
`StarletMemory::Read32` (3 246 échantillons),
|
||||
`ARMCore::TranslateVirtualAddress` (2 909), `StarletMemory::Write32` (2 613),
|
||||
`PowerPC::MMU::WriteToHardware` (2 420) et
|
||||
`StarletMemory::CalculateNANDECC` (1 918). Ce sont des **feuilles** : leur somme
|
||||
ne décrit pas une pile ni un chemin critique. Le thread GPU occupe aussi du
|
||||
CPU, mais il ne domine pas ce relevé. Les 218 millions d'écritures lentes
|
||||
JIT sont un compteur d'appels, pas 218 millions d'accès NAND.
|
||||
|
||||
Les compteurs de scopes échantillonnés distinguent NAND, journal, NAT, DMA,
|
||||
ARM/JIT et périphériques, avec zéro erreur de comptabilité. Ils mesurent du
|
||||
temps mur de tranches sélectionnées 1/1024, pas une durée CPU exhaustive ; ils
|
||||
ne justifient donc pas d'affirmer qu'un autre poste est nul. Les événements
|
||||
`Frame` et `Snapshot` natifs couvrent toute la session alors que les
|
||||
échantillons CPU Xperf sont filtrés ; les chiffres de FPS ci-dessus viennent
|
||||
de `cpu-threads-phase2.json`, qui borne **les deux** à la même fenêtre QPC.
|
||||
|
||||
## Décision
|
||||
|
||||
La première minute de mise à jour est surtout limitée par le thread principal
|
||||
d'émulation, mais aucun helper unique mesuré ne démontre à lui seul les ~21 %
|
||||
de réduction de temps par image nécessaires pour passer de la médiane observée
|
||||
à 60 FPS. Un simple gain de microbenchmark ECC ou TLB ne doit pas être présenté
|
||||
comme un correctif 60 FPS. Les écritures lentes sont le candidat à qualifier :
|
||||
le fast path direct SRAM écrit avait déjà régressé BootMii, donc élargir son
|
||||
masque sans savoir quelles adresses dominent serait risqué.
|
||||
|
||||
Prochain essai borné : la nouvelle copie initiale `P1-trace-003` est préparée
|
||||
et vérifiée. Activer `-ProfileJitMemory` dans cette copie seulement et relever
|
||||
dans `dolphin.log`
|
||||
les compteurs RAM/SRAM/MMIO et les adresses les plus fréquentes pendant le même
|
||||
début de mise à jour. Ce mode ajoute du coût et ne sert qu'à **classer les
|
||||
adresses**, pas à comparer ses FPS à la présente trace. Ensuite seulement,
|
||||
choisir une optimisation limitée à une famille d'adresses, ajouter des tests de
|
||||
fidélité BootMii/HBC/NAND et réaliser un A/B sans instrumentation sur deux NAND
|
||||
identiques. L'objectif de 60 FPS reste ouvert.
|
||||
|
||||
Le lancement du relevé ciblé est manuel depuis un PowerShell interactif, car
|
||||
une instance créée par l'outil de commande de l'agent s'est retrouvée invisible
|
||||
sur le bureau utilisateur :
|
||||
|
||||
```powershell
|
||||
cd C:\Users\tpetkovic\Desktop\dolphin
|
||||
.\Run-Wii-IOS-LLE.ps1 `
|
||||
-BuildDirectory .starlet_update_ab_20260913/build-P1-trace-003 `
|
||||
-UserDirectory .starlet_update_ab_20260913/P1-trace-003 `
|
||||
-Ethernet -ProfileJitMemory
|
||||
```
|
||||
|
||||
Fichiers de résultat locaux : `decoder-summary.json`, `xperf-summary.json`,
|
||||
`native-report.json`, `cpu-threads-phase2.json` dans le répertoire d'analyse
|
||||
indiqué ci-dessus. Un export Xperf complet, interrompu car disproportionné,
|
||||
a été supprimé ; l'ETL source et l'export ciblé sont conservés.
|
||||
|
||||
## Relevé ciblé `P1-trace-003` : écritures SRAM
|
||||
|
||||
La copie isolée `P1-trace-003` a été démarrée avec `-ProfileJitMemory`. La mise
|
||||
à jour est allée jusqu'au redémarrage/menu Wii (confirmé par l'utilisateur).
|
||||
Le journal a cessé de croître à 2 763 867 232 octets. L'analyse en lecture
|
||||
seule valide ses 651 690 transactions et 165 568 pages finales superposées.
|
||||
Le SYSCONF est valide ; les 9 contenus du menu v514 et les 15 d'IOS80 v6944
|
||||
correspondent à leurs empreintes TMD. SHA-256 du journal :
|
||||
`49b19327a9b0d7c3aa08c4d59e81365aa17b82ef7452939c07281cbd499b5b56`.
|
||||
Cela ne constitue pas une vérification exhaustive de tous les titres.
|
||||
|
||||
Entre les snapshots JIT de 11:57:06.905 (début des écritures de mise à jour)
|
||||
et 12:07:12.622 (fin des écritures), soit environ 606 s de temps mur :
|
||||
|
||||
| Compteur d'accès ARM lents | Delta |
|
||||
| --- | ---: |
|
||||
| SRAM | 1 024 033 027 (78,74 % des accès classés) |
|
||||
| MMIO | 255 829 918 |
|
||||
| Autres | 20 598 539 |
|
||||
| RAM | 0 |
|
||||
| Lectures, toutes régions | 292 651 794 |
|
||||
| Écritures, toutes régions | 1 007 809 690 |
|
||||
| Écritures SRAM | 971 531 207 (96,4 % des écritures lentes) |
|
||||
|
||||
Les pages d'aperture SRAM `0x00` et `0x19` portent respectivement
|
||||
556 332 042 et 348 178 857 écritures lentes, soit **93,1 % des écritures
|
||||
SRAM** de cette fenêtre. L'alias bas n'augmente pas : ce trafic passe par
|
||||
l'alias haut. Les adresses qui reviennent le plus dans l'échantillonnage
|
||||
1/256 sont notamment `0xffff97a0` et `0xfffe03c0` en écriture ; les lectures
|
||||
MMIO comprennent `0x0d800038` et `0x0d80003c`. Le classement par page est
|
||||
exact dans les compteurs, tandis que les adresses individuelles ne sont que
|
||||
des échantillons (huit adresses au maximum par snapshot).
|
||||
|
||||
**Conséquence :** les écritures SRAM sont un candidat ciblé, pas un gain de
|
||||
FPS déjà établi. Ce run est instrumenté et ne doit pas être comparé en vitesse
|
||||
au run natif `P1-trace-002`. Le JIT conserve volontairement les écritures
|
||||
SRAM sur le bus exact : une ancienne écriture directe, même limitée aux pages
|
||||
`0x00`/`0x19`, avait bloqué BootMii à son initialisation matérielle. Avant de
|
||||
réintroduire un fast path, il faut expliquer cette divergence et vérifier
|
||||
boot0/split/alias/endianness ainsi que le cycle BootMii → menu → HBC. Ensuite,
|
||||
seul un A/B non instrumenté sur deux copies identiques peut qualifier le gain
|
||||
sur la mise à jour réelle et la cible de 60 FPS.
|
||||
|
||||
## Essai SRAM ciblé : rejeté après A/B natif
|
||||
|
||||
Un candidat a court-circuité le bus dans le helper JIT uniquement pour les
|
||||
stores alignés de 32 bits sur les pages SRAM hautes `0x00` et `0x19`, avec
|
||||
gardes boot0/split et chemin bus conservé ailleurs. Le test dédié des gardes
|
||||
et **153 tests** `Starlet*` ont passé. BootMii puis Wii ont démarré dans le
|
||||
profil isolé `P1-trace-004`. HBC est absent de cette NAND ; ce trajet n'a pas
|
||||
été testé. Le binaire candidat figé (SHA-256
|
||||
`B5F3C3BA1D6EE2C86E5A3EB685F3B3D5FCEF2674C51EA137B697903F9E210006`)
|
||||
reste dans `build-P1-trace-005` pour reproduire l'essai, mais le raccourci a
|
||||
été **retiré du source courant** après les mesures ci-dessous.
|
||||
|
||||
`P1-trace-005` (candidat) et `P1-trace-006` (témoin, exécutable SHA-256
|
||||
`D809E04E2E8E900DB06D3813A67805E66EADB2BB79924CB8E805CB724360EAD4`)
|
||||
partaient des mêmes 31 fichiers, d'un journal vérifié de 533 705 344 octets
|
||||
et de la même configuration, hormis les chemins isolés. Le profilage détaillé
|
||||
était désactivé dans les deux builds. Une mesure hôte légère a relevé toutes
|
||||
les 10 s la taille du journal et le temps CPU du processus, sans lire la
|
||||
mémoire invitée ni injecter d'entrée. Les durées ci-dessous interpolent les
|
||||
franchissements des **mêmes** seuils de 600 Mo et 2,7 Go ; l'incertitude
|
||||
temporelle reste de l'ordre de l'intervalle d'échantillonnage.
|
||||
|
||||
| Mesure 600 Mo → 2,7 Go | Candidat | Témoin |
|
||||
| --- | ---: | ---: |
|
||||
| Temps mur interpolé | 434,7 s | 402,4 s |
|
||||
| Temps CPU du processus | 501,5 s | 459,8 s |
|
||||
| Journal final | 2 763 867 232 octets | 2 733 507 520 octets |
|
||||
|
||||
Les deux mises à jour ont abouti et les journaux passent la vérification
|
||||
complète des transactions. Le SYSCONF est valide ; le menu v514 et IOS80 v6944
|
||||
ont respectivement leurs 9 et 15 contenus cohérents avec les TMD. L'utilisateur
|
||||
a aussi trouvé le témoin plus fluide. Aucun flux FPS précis n'a été enregistré
|
||||
pour cet A/B. C'est un seul passage par variante, avec une taille finale de
|
||||
journal légèrement différente : il ne démontre pas la taille exacte d'une
|
||||
régression, mais **ne montre aucun gain**. Le nombre d'accès SRAM n'était donc
|
||||
pas, à lui seul, une justification suffisante pour ce raccourci. Ne pas le
|
||||
promouvoir. Les captures brutes restent dans `P1-trace-005/Capture` et
|
||||
`P1-trace-006/Capture` pour réanalyse.
|
||||
@@ -0,0 +1,802 @@
|
||||
# Étude des performances de la mise à jour Wii native
|
||||
|
||||
Date : 13 septembre 2026. Profil étudié : `.starlet_formatter_test_20260913`.
|
||||
La réussite de la mise à jour est confirmée par l'utilisateur.
|
||||
|
||||
**Méthode à suivre depuis le bilan F du 19 septembre :**
|
||||
[protocole de diagnostic P1](Wii_LLE_Performance_Diagnostic_Protocol.md).
|
||||
Les propositions d'essais ci-dessous constituent l'historique, pas une instruction de
|
||||
relancer une série de mises à jour. L'attribution du coût doit précéder le prochain correctif.
|
||||
|
||||
## Conclusion
|
||||
|
||||
La priorité est le chemin mémoire du JIT ARM, pas un changement de moteur JIT ou
|
||||
une désactivation de la persistance NAND. Un premier prototype conservateur réduit
|
||||
le temps d'une boucle d'écritures SRAM d'environ **9,5 %**. Les lectures SRAM lentes
|
||||
offrent un potentiel plus important, mais leur élargissement nécessite une validation
|
||||
matérielle et de la chaîne de démarrage. Le journal NAND peut être beaucoup plus compact,
|
||||
sans que la réduction de sa taille se traduise proportionnellement en temps gagné.
|
||||
|
||||
Lors de l'étude initiale, aucun correctif de production n'était déployé : la build interactive,
|
||||
la NAND mise à jour et les réglages de vitesse restaient inchangés. Les sections 5 et 6 décrivent
|
||||
les essais ultérieurs, après compilation des correctifs SRAM. Les prototypes de format de journal
|
||||
restent des exécutables distincts et ne sont pas utilisés par les builds interactives.
|
||||
|
||||
## 1. Mesures pendant la mise à jour
|
||||
|
||||
- PID 27108, lancé à 00:52:47, Ethernet AX88772 et NAT actifs.
|
||||
- À 01:00, 1 226 trames reçues supplémentaires en environ onze secondes ; aucune
|
||||
erreur de polling NAT. Cela prouve une progression, pas l'absence de toute limitation réseau.
|
||||
- Thread principal : 76 à 83 % d'un cœur selon les fenêtres mesurées.
|
||||
- Thread de rendu : environ 88 % des échantillons en attente.
|
||||
- Vitesse d'émulation : phases à environ 65–76 %, alternant avec des phases à pleine vitesse.
|
||||
- Environ 99,6 % des instructions ARM comptées par le JIT sont natives. Cette mesure
|
||||
ne signifie pas que les accès mémoire associés évitent les appels C++.
|
||||
- Les 21,58 % d'échantillons dans `NtWaitForSingleObject` ne sont pas attribués au disque :
|
||||
sans piles d'appels, le limiteur de vitesse et d'autres attentes restent des explications possibles.
|
||||
|
||||
La capture CPU et les compteurs sont conservés dans
|
||||
`.starlet-profile/update-profile-20260913-0100.txt` et
|
||||
`.starlet-profile/update-diagnosis-20260913.md`.
|
||||
|
||||
## 2. Journal NAND réel : beaucoup d'octets, mais pas une preuve de domination du disque
|
||||
|
||||
Une analyse binaire en lecture seule a vérifié les sommes de contrôle de toutes les
|
||||
transactions, sans déchiffrer la NAND. Le journal final représente **2 928 558 112 octets**.
|
||||
Le seuil de départ est sa taille observée avant la session, **533 705 344 octets**.
|
||||
Les chiffres suivants couvrent donc la session après ce seuil, pas un chronométrage
|
||||
strict des seuls appels de l'interface de mise à jour.
|
||||
|
||||
| Catégorie | Transactions | Octets |
|
||||
|---|---:|---:|
|
||||
| Programmation d'une page | 555 504 | 1 193 222 592 |
|
||||
| Effacement d'un bloc de 64 pages | 8 871 | 1 201 630 176 |
|
||||
| Total après le seuil | 564 375 | 2 394 852 768 |
|
||||
|
||||
Chaque effacement sérialise actuellement 64 pages entièrement remplies de `0xff`,
|
||||
soit **135 456 octets** avec les métadonnées et la somme de contrôle. Un enregistrement
|
||||
décrivant exactement le bloc effacé pourrait représenter la même opération en **36 octets**.
|
||||
L'estimation sur cette session passe ainsi de 2,395 Go à **1,194 Go**, environ **50 % de moins**.
|
||||
|
||||
Il n'y a que 7 048 réécritures de page strictement identiques parmi 1 123 248 enregistrements
|
||||
de page après le seuil, soit environ 0,63 %. La simple suppression des doublons n'est donc
|
||||
pas le meilleur premier levier sur cette charge.
|
||||
|
||||
### Comparaison synthétique avec la bibliothèque de production
|
||||
|
||||
Même charge par essai : 128 effacements, chacun suivi de 64 programmations ; 8 320 transactions.
|
||||
Le code de production `NANDJournal::Append` est appelé directement pour la référence.
|
||||
Les trois variantes conservent un `fflush` par transaction. Trois répétitions, ordre tournant.
|
||||
Les opérations synthétiques sont relues indépendamment : sommes de contrôle et pages finales
|
||||
identiques. Les fichiers synthétiques sont ensuite supprimés individuellement.
|
||||
|
||||
| Variante | Temps médian | Taille |
|
||||
|---|---:|---:|
|
||||
| Production actuelle | 86,377 ms | 34 934 816 octets |
|
||||
| Un seul `WriteArray` avec record + checksum | 94,858 ms | 34 934 816 octets |
|
||||
| Effacements compacts + écriture regroupée | 69,166 ms | 17 601 056 octets |
|
||||
|
||||
Le regroupement seul n'est pas un gain démontré. L'encodage compact réduit d'environ
|
||||
20 % le temps de ce banc d'essai, et de 49,6 % le volume. Les chiffres absolus sont ceux
|
||||
du cache disque et du processeur de cette machine ; ils n'incluent pas les calculs et
|
||||
la planification d'IOS, les contrôleurs NAND/AES/ECC, ni les échanges réseau. On ne peut
|
||||
pas transformer ces pourcentages en promesse de gain global sur la mise à jour.
|
||||
|
||||
**Le prototype compact n'est pas un format de journal déployable** : il utilise un marqueur
|
||||
expérimental non reconnu par le lecteur actuel. Une intégration réclame un format versionné,
|
||||
une lecture des anciens journaux, une migration sauvegardée et des tests de transactions
|
||||
interrompues, corruption et retour à une ancienne build. `fflush` est conservé à l'identique ;
|
||||
ces essais ne prouvent pas une garantie supplémentaire contre une panne électrique de l'hôte.
|
||||
|
||||
## 3. Mémoire ARM : origine concrète des appels lents
|
||||
|
||||
Dans `ARMJitX64::EmitFastmemAddress` :
|
||||
|
||||
- Les lectures SRAM directes sont limitées aux pages logiques `00, 10, 12, 14, 19, 1e`.
|
||||
- Les écritures SRAM sont toutes rejetées vers le bus exact, après plusieurs vérifications
|
||||
qui ne peuvent actuellement conduire à une écriture directe.
|
||||
- Les transferts de listes de registres sont exclus du chemin SRAM direct.
|
||||
- Des pages très sollicitées dans les compteurs de mise à jour, telles que `04, 16, 15`,
|
||||
ne font pas partie de la liste des lectures directes.
|
||||
- Les chemins lents paient les appels généré → C++, la classification du bus, le calcul des
|
||||
alias SRAM, et l'instrumentation. Il ne suffit donc pas d'afficher « 99,6 % natif ».
|
||||
|
||||
Un banc d'essai utilise le véritable `ARMCore`/JIT et le véritable bus `StarletMemory` pour
|
||||
les données SRAM. Seul le petit programme Thumb est placé dans une RAM synthétique.
|
||||
Il ne charge aucun dump et n'initialise aucun profil. Les registres et la mémoire finale sont vérifiés.
|
||||
|
||||
Pour un même programme de lecture et la même adresse `0xffff4000`, autoriser le pointeur
|
||||
direct déjà validé prend environ **14 ms**, contre **70 ms** en forçant le bus exact,
|
||||
pour 8 millions d'instructions : environ **5 fois moins de temps sur cette boucle**.
|
||||
Les lectures de la page non admise `0xffff6000` et les écritures restent sur le chemin lent.
|
||||
Ce microbenchmark utilise une MMU désactivée, un programme homogène et pas de périphériques
|
||||
en activité : le facteur cinq **n'est pas** un facteur cinq sur IOS ou sur la mise à jour.
|
||||
|
||||
### Prototype conservateur : rejoindre plus tôt le même chemin lent
|
||||
|
||||
Le prototype ajoute seulement `sram_access == Write` au rejet initial SRAM, puisque ces
|
||||
écritures sont déjà rejetées inconditionnellement plus loin. Il ne permet aucune écriture
|
||||
directe nouvelle, ne supprime aucun appel au bus et ne modifie pas le comportement d'IOS.
|
||||
|
||||
Comparaison alternée **A/B/B/A/A/B**, trois répétitions par exécutable, affinité sur le même
|
||||
processeur logique 0, 32 millions d'instructions par boucle, compilation initiale exclue :
|
||||
|
||||
| Boucle d'écritures SRAM | Médiane, 9 échantillons |
|
||||
|---|---:|
|
||||
| Production | 267,285 ms |
|
||||
| Rejet anticipé | 241,842 ms |
|
||||
|
||||
Soit **9,5 % de temps en moins** sur cette boucle. Les 16 millions d'écritures par mesure
|
||||
passent toujours par le chemin lent et le résultat architectural reste identique.
|
||||
Les fluctuations de fréquence/ordonnancement subsistent ; les résultats ne constituent
|
||||
pas un gain global mesuré. Le prototype lié aux tests existants passe **176 tests sur 22 suites**,
|
||||
y compris les tests NAT avec le runtime présent ; deux benchmarks préexistants sont désactivés.
|
||||
La validation interactive BootMii → IOS → menu → HBC → rechargement IOS reste à effectuer.
|
||||
|
||||
## 4. Ordre proposé pour les correctifs
|
||||
|
||||
1. **Rejet anticipé des écritures SRAM** : petite modification, gain local mesuré, même bus,
|
||||
tests ciblés passés. Valider une build séparée sur toute la chaîne avant de l'adopter.
|
||||
2. **Lectures SRAM chaudes** : caractériser précisément les pages et leurs alias, puis étendre
|
||||
la voie directe par classe d'accès avec tests interpréteur/JIT, deux endiannesses,
|
||||
boot0 actif/inactif, split, trous, frontières et rechargements IOS. Potentiel plus élevé.
|
||||
3. **Journal compact pour les effacements** : format versionné et récupération testée,
|
||||
mêmes opérations invitées et même niveau de persistance avant acquittement.
|
||||
4. **Chronométrage par phase dans une exécution comparable** : temps ARM, attente/limiteur,
|
||||
appels du bus, contrôle NAND et journal, débit réseau ; comparer des copies d'un même
|
||||
état pré-mise à jour. Ne pas reformater ni rétrograder la NAND actuelle pour fabriquer ce test.
|
||||
|
||||
Ne pas réactiver globalement les écritures SRAM directes : le code documente une précédente
|
||||
régression BootMii malgré des tests de bornes isolés. Ne pas désactiver les contrôles IOS,
|
||||
modifier les horloges Wii, ou différer arbitrairement les sauvegardes pour afficher plus de FPS.
|
||||
|
||||
## 5. Extension des lectures SRAM mesurées (13 septembre, 23 h)
|
||||
|
||||
Le rejet anticipé des écritures a été compilé puis lancé sur le profil mis à jour ; l'utilisateur
|
||||
a confirmé que ce premier essai fonctionnait. La chaîne complète de rechargements reste un
|
||||
critère de validation distinct, pas une conséquence des tests unitaires.
|
||||
|
||||
La trace arrêtée à 22:52 contient 73 117 662 lectures SRAM lentes. Les pages `04, 16, 15, 1d`
|
||||
en représentent 47 810 655, soit environ 65,4 %. Avec `1c`, également observée pendant l'étude
|
||||
de la mise à jour, elles sont désormais admises pour les lectures scalaires directes.
|
||||
La liste totale est `00, 04, 10, 12, 14, 15, 16, 19, 1c, 1d, 1e`.
|
||||
Un masque de 32 bits remplace la chaîne de comparaisons. Les états boot0/split sont toujours
|
||||
lus à l'exécution ; trous, bornes, écritures et listes de registres gardent leur traitement existant.
|
||||
Ni les horloges, ni les instructions IOS, ni le journal NAND ne sont modifiés par ce correctif.
|
||||
|
||||
### Validation hors firmware
|
||||
|
||||
Le nouveau `SRAMReadTest.cpp` utilise le vrai `StarletMemory` pour les données, sans initialiser
|
||||
de dump ou de profil. Il vérifie :
|
||||
|
||||
- les lectures ARM/Thumb de mots, octets, demi-mots et valeurs signées, dans les deux endiannesses ;
|
||||
- 37 908 combinaisons d'alias, pages, alignements/frontières et changements boot0/split,
|
||||
en comparant les 16 registres et CPSR à l'interpréteur, sans modifier les 96 Kio de SRAM ;
|
||||
- la réutilisation des blocs compilés lors des changements de mapping matériel ;
|
||||
- un remappage de page SRAM après une invalidation TLB réellement exécutée par le code invité ;
|
||||
- zéro appel de lecture de données au bus pour les nouveaux accès alignés autorisés.
|
||||
|
||||
Avant le correctif, les tests de chemins rapides échouaient comme attendu sur les compteurs,
|
||||
alors que les résultats mémoire correspondaient. Après le correctif, **179 tests sur 23 suites**
|
||||
passent, dont les tests existants de protection boot0, écritures SRAM, NAND, appairage et NAT.
|
||||
Deux benchmarks préexistants restent désactivés.
|
||||
|
||||
### Comparaison A/B
|
||||
|
||||
Comparaison alternée A/B/B/A/A/B après la compilation, sur le même processeur logique 0,
|
||||
avec neuf échantillons par cas, 32 millions d'instructions et compilation initiale exclue :
|
||||
|
||||
| Boucle | Avant, médiane | Après, médiane |
|
||||
|---|---:|---:|
|
||||
| Lecture page `16` (`0xffff6000`), nouvellement directe | 263,97 ms | 43,44 ms |
|
||||
| Lecture page `14`, déjà directe | 45,39 ms | 45,31 ms |
|
||||
| Lecture page `14`, bus forcé | 245,27 ms | 224,46 ms |
|
||||
| Écriture SRAM, toujours par le bus | 206,77 ms | 215,03 ms |
|
||||
|
||||
Le cas ciblé passe de 16 millions à zéro lecture lente et prend environ **6 fois moins de temps**.
|
||||
Les valeurs finales sont vérifiées pour tous les échantillons. Les cas de contrôle montrent
|
||||
encore la variabilité de l'hôte ; ne pas interpréter leurs écarts comme des correctifs supplémentaires.
|
||||
Ce banc homogène sans MMU ni périphériques actifs **ne mesure pas** la durée d'une mise à jour
|
||||
Wii, ni les FPS de la chaîne complète. Ces gains réels restent à mesurer sur la build interactive.
|
||||
Le premier chronométrage effectué pendant la compilation est exclu de cette comparaison.
|
||||
|
||||
La build précédente et le journal courant (3 080 124 160 octets) ont été sauvegardés dans
|
||||
`.starlet-profile/before-sram-read-20260913-230752/`. Les SHA-256 de la copie et du journal
|
||||
actif ont été comparés et sont identiques. Aucun compactage ni retour arrière de la NAND
|
||||
n'a été réalisé. La nouvelle build reste en validation interactive, pas un jalon final validé.
|
||||
|
||||
## 6. Préparation d'une vraie comparaison de mise à jour
|
||||
|
||||
À la demande de l'utilisateur, deux profils indépendants ont été préparés dans
|
||||
`.starlet_update_ab_20260913/A` et `B`. La NAND de départ est le préfixe de 533 705 344 octets
|
||||
du journal archivé : exactement la taille observée avant la session de mise à jour initiale.
|
||||
Extraction dans un nouveau fichier uniquement ; aucune troncature/restauration d'un journal actif.
|
||||
Ses 125 881 transactions, le SYSCONF et les 24 contenus du menu/IOS80 ont été revérifiés.
|
||||
SHA-256 du préfixe : `07b2f4bc543cfd4203efc448538505e9d503b2727c16aaff8d8c0b286d8b4f0c`.
|
||||
|
||||
Les fichiers des deux profils sont identiques, sauf leurs chemins de sortie isolés. SD et runtime
|
||||
sont copiés ; executables et PDB sont figés séparément. A inclut déjà le rejet anticipé des écritures,
|
||||
B ajoute les lectures scalaires étendues : cette comparaison isole donc cette seconde optimisation.
|
||||
Les journaux des profils habituels ont été contrôlés inchangés après préparation.
|
||||
|
||||
A a été lancé le 13 septembre à 23:26:56 (PID 1696), Ethernet actif, avec une capture en lecture
|
||||
seule des performances, compteurs NAT/CPU/I/O et taille du journal toutes les dix secondes.
|
||||
Le coût de chaque interrogation est enregistré : les premières lectures réussies coûtent environ
|
||||
0,7 seconde de temps mural, ce qui impose de garder la même instrumentation dans les deux essais
|
||||
et de ne pas négliger son impact potentiel. La première lecture, trop précoce pendant l'initialisation,
|
||||
a échoué sans affecter Dolphin ; les suivantes fonctionnent. La capture n'injecte pas d'entrées,
|
||||
n'écrit pas en mémoire et ne suspend pas les threads.
|
||||
|
||||
Cet essai du 13 septembre n'a pas de confirmation de fin. Le 16 septembre, son dossier complet
|
||||
a été conservé sous `A-interrupted-20260913`, puis A recréé à l'identique depuis B encore intact.
|
||||
Les empreintes de tous les fichiers du nouveau A correspondent à son manifeste initial.
|
||||
|
||||
## 7. Résultats de la paire native A/B du 16 septembre
|
||||
|
||||
L'utilisateur confirme la réussite des deux mises à jour. Aucun réglage d'horloge, accès réseau,
|
||||
contrôle IOS ou format du journal n'a été modifié entre les deux exécutables figés.
|
||||
|
||||
| Mesure | A, avant extension des lectures | B, après extension |
|
||||
|---|---:|---:|
|
||||
| Durée entre signalements début/fin | 13 min 29 s | 11 min 33 s |
|
||||
| FPS médians des relevés | 22,79 | 28,33 |
|
||||
| Vitesse d'émulation médiane | 46,3 % | 55,0 % |
|
||||
| Plus bas FPS échantillonné | 8,42 | 7,28 |
|
||||
| Échantillons sous 90 % de vitesse | 68 / 73 | 56 / 63 |
|
||||
| Accroissement du journal entre premiers/derniers relevés sélectionnés | 2 190 232 512 octets | 2 190 232 512 octets |
|
||||
| Erreurs de polling NAT | 0 | 0 |
|
||||
|
||||
Sur cette paire, **115,5 secondes de moins, soit environ 14,3 % de réduction de durée** sont
|
||||
observées. Ce n'est ni un gain global de 6×, ni un fonctionnement garanti à 50–60 FPS. Les chutes
|
||||
à 7–9 FPS demeurent. Les FPS sont des relevés discrets, pas une distribution pondérée par image.
|
||||
|
||||
Les heures de début/fin proviennent des signalements et inspections, pas d'un chronométrage
|
||||
exact du clic et de l'écran de réussite. Pour recouper, les franchissements échantillonnés de
|
||||
600 Mo à 2700 Mo de journal prennent 685,6 s dans A et 582,6 s dans B (environ 15 % de moins).
|
||||
Ils ont une granularité d'environ onze secondes et ne désignent pas exactement les mêmes
|
||||
transactions. Conditions serveur, cache/température/charge hôte et capture restent des facteurs
|
||||
de variation ; une paire séquentielle ne mesure pas à elle seule l'effet causal exact du correctif.
|
||||
|
||||
### Profilage complémentaire pendant la chute de B
|
||||
|
||||
À la demande de diagnostic, un échantillonnage des pointeurs d'instruction de 15 secondes a été
|
||||
ajouté entre 17:16:47 et 17:17:03. Il suspend/reprend brièvement les threads. **Ce surcoût n'était
|
||||
pas présent sur A**, et reste inclus dans la durée observée de B ; il ne faut pas soustraire
|
||||
arbitrairement quinze secondes. La fenêtre est marquée dans les résultats.
|
||||
|
||||
- Thread d'émulation : 14,000 secondes CPU en 15 secondes, soit environ 93,3 % d'un cœur.
|
||||
- Allocation identifiée du JIT ARM : 393 / 953 échantillons du thread, environ 41,2 %.
|
||||
- Accès `StarletMemory`, traduction d'adresses, fonctions mémoire et quelques chemins interprétés
|
||||
apparaissent également parmi les points chauds.
|
||||
- Thread de rendu : environ 88,9 % des échantillons en attente, 1,438 seconde CPU en 15 secondes.
|
||||
- Sur 3,828 secondes couvertes par cinq compteurs de cette fenêtre : environ un million
|
||||
d'écritures SRAM lentes par seconde. Il s'agit d'accès mémoire ARM, pas d'appels d'écriture disque,
|
||||
et le nombre d'accès n'est pas une part de temps CPU.
|
||||
|
||||
Le frein observé est principalement côté exécution CPU/mémoire, pas le thread de rendu.
|
||||
Les données ne démontrent pas que le journal NAND domine le temps. Prochaines cibles à mesurer :
|
||||
écritures SRAM via le bus, traduction, dispatch et chemins de repli, en conservant les protections
|
||||
et la cohérence. Ne pas réactiver globalement les écritures directes qui avaient régressé BootMii.
|
||||
|
||||
### Intégrité à l'arrêt et conservation
|
||||
|
||||
Après fermeture confirmée, les journaux ont été relus intégralement : **651 682 transactions valides
|
||||
pour A, 651 690 pour B**. Les deux SYSCONF sont valides ; les 24 contenus du menu v514 et
|
||||
de l'IOS80 v6944 correspondent à leurs empreintes TMD. Il ne s'agit pas d'un audit exhaustif
|
||||
de tous les titres installés. Les journaux finaux font respectivement 2 763 850 048 et
|
||||
2 763 867 232 octets ; leurs empreintes et preuves sont conservées dans chaque dossier `Capture`.
|
||||
Les profils habituels, les dumps d'origine et la graine pré-mise à jour n'ont pas été remplacés.
|
||||
|
||||
## 8. Optimisation du bus SRAM et des marches de tables (16–19 septembre)
|
||||
|
||||
Le profilage de B a conduit à deux changements ciblés, sans nouveau chemin d'écriture directe
|
||||
dans le JIT et sans modification des horloges, du NAT ou du journal NAND :
|
||||
|
||||
- Les écritures SRAM alignées de 16/32 bits sont traitées avant le décodage MMIO. Un accès aligné
|
||||
reste dans un seul segment ; les protections boot0 et le bit SM sont relus à chaque accès.
|
||||
Les accès non alignés conservent le chemin précédent, y compris aux limites des banques.
|
||||
- Le calcul de banque SRAM utilise l'échange du bit d'aperture, suivi du contrôle des 96 Kio
|
||||
physiques. Les trous ne deviennent pas des alias valides.
|
||||
- Les marches de tables ordinaires ne demandent plus un pointeur de descripteur inutilisé.
|
||||
Le JIT continue à obtenir ces pointeurs pour valider ses blocs après maintenance du TLB.
|
||||
Les lectures de descripteurs et les règles de traduction ne changent pas.
|
||||
|
||||
### Vérification hors firmware
|
||||
|
||||
**182 tests passent**. Les nouveaux tests confrontent chaque octet de trois apertures au modèle
|
||||
de mapping indépendant (1 572 864 lectures), puis les écritures larges à un oracle octet par octet
|
||||
sur toutes les fenêtres miroirs, les limites, les modes SM/boot0 et leur retour à l'état initial.
|
||||
Ils comparent toute la SRAM après chaque écriture. La traduction est vérifiée en big/little-endian
|
||||
pour les sections et les tables coarse/fine (pages large, small et tiny). Les tests existants de
|
||||
DMA, IRQ, MMU, changement de contexte JIT, NAND et réseau restent inclus.
|
||||
|
||||
### Mesure synthétique avant/après
|
||||
|
||||
Même programme ARM/Thumb, résultats vérifiés, bibliothèque Release, CPU logique 0, exécutables
|
||||
avant/après distincts. Deux séries alternées, ABBAAB puis BAABBA, donnent chacune neuf mesures
|
||||
par variante et par cas. Aucun émulateur ni compilateur n'est lancé pendant la mesure.
|
||||
Le PC montre une forte variabilité ; les durées CPU du thread sont aussi enregistrées mais leur
|
||||
granularité est limitée. Les valeurs suivantes sont les médianes de durée murale en millisecondes :
|
||||
|
||||
| Cas | Avant, série 1 | Après, série 1 | Avant, série 2 | Après, série 2 |
|
||||
|---|---:|---:|---:|---:|
|
||||
| 16 millions d'écritures SRAM, alias `ffff9000` | 271,06 | 149,17 | 273,50 | 156,40 |
|
||||
| Même charge, alias bas `0d419000` | 307,16 | 154,17 | 383,38 | 176,50 |
|
||||
| Lecture déjà directe, contrôle `ffff4000` | 56,82 | 56,55 | 74,31 | 71,17 |
|
||||
| Marches de tables forcées, charge interprétée | 174,94 | 124,29 | 318,02 | 136,92 |
|
||||
|
||||
Le cas principal d'écriture montre environ **43–45 % de durée en moins sur ce microbanc**.
|
||||
Les 16 millions d'écritures passent toujours par le bus, avec les mêmes résultats ; aucune n'est
|
||||
supprimée. La variabilité, surtout pour la traduction, interdit une extrapolation précise.
|
||||
Ce résultat ne signifie pas 43–45 % de moins sur une mise à jour complète, ni 50–60 FPS garantis.
|
||||
La validation native de cette nouvelle optimisation est décrite en section 9 ;
|
||||
les mises à jour A/B de la section 7 concernaient uniquement l'extension des lectures.
|
||||
Les profils et journaux réels ne sont pas remplacés par ces tests.
|
||||
|
||||
### Préparation du test natif C
|
||||
|
||||
Le 19 septembre, un troisième profil `C` et un exécutable figé `build-C` sont créés sans écraser A/B.
|
||||
Tous les fichiers du profil initial correspondent aux empreintes du manifeste initial B, hormis
|
||||
les chemins de sortie redirigés vers C. Les copies intactes de TimePlayed, SRAM GameCube et SD brute
|
||||
sont récupérées depuis le profil de test du formateur, sans le modifier. La NAND de départ est à
|
||||
nouveau vérifiée intégralement. Premier lancement à 11:48 Paris, capture de compteurs active.
|
||||
Sa fenêtre étant invisible pour l'utilisateur dans le contexte isolé, il est relancé sur le bureau
|
||||
visible à 11:52, après confirmation que le journal n'avait pas changé. L'utilisateur ferme ensuite
|
||||
cette instance après le démarrage natif ; elle est relancée à 11:55 en conservant ses changements,
|
||||
sans réinitialiser la NAND. Le journal avant cette dernière relance est vérifié : 536 348 704 octets,
|
||||
126 491 transactions valides et contenus menu/IOS80 intacts. Seule la capture du dernier PID 15540
|
||||
est utilisée pour mesurer la mise à jour.
|
||||
Les essais ont lieu à des dates différentes, ce qui ajoute des variations possibles de charge
|
||||
hôte et de conditions serveur.
|
||||
|
||||
## 9. Résultat natif C du 19 septembre
|
||||
|
||||
L'utilisateur confirme la fin de la mise à jour, puis ferme Dolphin pour la validation finale.
|
||||
|
||||
| Mesure | B, extension des lectures | C, bus SRAM et marches de tables optimisés |
|
||||
|---|---:|---:|
|
||||
| Durée entre signalements début/fin | 11 min 33 s | 9 min 07 s |
|
||||
| FPS médians des relevés | 28,33 | 41,61 |
|
||||
| Plus bas FPS échantillonné | 7,28 | 13,17 |
|
||||
| Vitesse d'émulation médiane | 55,0 % | 86,8 % |
|
||||
| Relevés sous 90 % de vitesse | 56 / 63 | 27 / 51 |
|
||||
| Temps CPU du processus entre relevés sélectionnés | 796,91 s | 604,77 s |
|
||||
| Erreurs de polling NAT pendant la fenêtre | 0 | 0 |
|
||||
|
||||
La durée observée diminue de **146,4 secondes, environ 21,1 %**, avec une nette amélioration des
|
||||
FPS échantillonnés. En recoupement, le passage échantillonné de 600 Mo à 2700 Mo de journal prend
|
||||
439,8 s dans C contre 582,6 s dans B, environ 24,5 % de moins. Ces seuils sont espacés d'environ
|
||||
onze secondes et ne représentent pas exactement les mêmes transactions.
|
||||
|
||||
Ce n'est pas une mesure causale isolée : les signalements sont des repères approximatifs,
|
||||
les journées/charges hôte et conditions serveur diffèrent, C a été redémarré avant la mise à jour,
|
||||
et B comporte une fenêtre supplémentaire de profilage hôte de quinze secondes. Les relevés FPS
|
||||
ne sont pas pondérés par image ; 13,17 FPS est le minimum échantillonné, pas le minimum garanti
|
||||
sur toutes les images. **L'objectif de 50–60 FPS constants n'est pas encore atteint.**
|
||||
|
||||
Après fermeture, le journal C est intégralement valide : **651 746 transactions**, 2 763 987 520
|
||||
octets, 165 120 pages superposées, génération 821 612. SYSCONF est valide et les 24 contenus du
|
||||
menu v514/IOS80 v6944 correspondent aux empreintes TMD. Les autres titres ne sont pas vérifiés
|
||||
par ce contrôleur. SHA256 final :
|
||||
`81b402d72c7c5fbe38e77a234212125488e0442560b5d0ba73c7a2da800fde56`.
|
||||
La NAND C et ses mesures sont conservées sans remplacer les résultats A/B, la graine initiale
|
||||
ou les profils habituels. Aucun commit ni push n'a été effectué pour cette nouvelle étape.
|
||||
|
||||
## 10. Copies DMA par blocs — candidat D du 19 septembre
|
||||
|
||||
Les phases lentes de C restent notamment visibles pendant le transfert et l'installation :
|
||||
les relevés entre 10:04:51 et 10:06:06 UTC descendent vers 13–17 FPS, alors que le journal progresse.
|
||||
Le code des périphériques copiait encore les buffers DMA octet par octet. En MEM1/MEM2, chaque
|
||||
octet repassait par la résolution de la mémoire hôte. Le profil hôte de B avait déjà échantillonné
|
||||
`GetPointerForRange`, `Read_U8` et les chemins associés ; cela motive une mesure ciblée, mais ne
|
||||
quantifie pas leur contribution exacte à C.
|
||||
|
||||
Le candidat D résout une plage contiguë une seule fois, puis utilise une copie par blocs pour
|
||||
AES, SHA, les données/spare/ECC NAND, les buffers/descripteurs OHCI et les transferts SD.
|
||||
Seules les plages entièrement contenues dans MEM1, MEM2 ou les 96 Kio physiques de SRAM basse
|
||||
sont accélérées. La SRAM DMA ignore toujours SM et le recouvrement boot0 du CPU. Les trous,
|
||||
miroirs hauts, registres, franchissements de limites et débordements d'adresse restent sur le
|
||||
chemin octet par octet. Les tampons temporaires restent séparés de la mémoire invitée ; AES
|
||||
capture toujours toute son entrée avant d'écrire une sortie éventuellement superposée.
|
||||
Ni les temporisations, ni le format/flush du journal NAND, ni les traitements réseau ne changent.
|
||||
|
||||
### Microbanc et validation
|
||||
|
||||
Le banc utilise de vraies commandes MMIO du moteur AES en **mode copie, chiffrement désactivé**,
|
||||
pour isoler le coût DMA, sans NAND, firmware, SD ou réseau. Chaque cas transfère 64 Mio et vérifie
|
||||
tous les octets de sortie ainsi que les registres source/destination/commande. Ordre ABBAAB,
|
||||
trois répétitions par exécution, neuf mesures par cas/version, même cœur hôte fixé.
|
||||
|
||||
| Banque / taille par commande | Médiane avant | Médiane après |
|
||||
|---|---:|---:|
|
||||
| MEM1 / 2 Kio | 1708,93 ms | 27,42 ms |
|
||||
| MEM1 / 16 Kio | 1669,52 ms | 10,95 ms |
|
||||
| MEM2 / 2 Kio | 2247,41 ms | 26,41 ms |
|
||||
| MEM2 / 16 Kio | 2173,30 ms | 10,57 ms |
|
||||
| SRAM / 2 Kio | 301,39 ms | 28,91 ms |
|
||||
| SRAM / 16 Kio | 265,90 ms | 12,37 ms |
|
||||
|
||||
La variabilité hôte est importante, même à affinité constante. Les temps CPU sont enregistrés,
|
||||
mais leur granularité de 15,625 ms limite la précision des cas accélérés. Ces chiffres ne sont
|
||||
**ni une mesure du chiffrement AES, ni une accélération annoncée de la mise à jour complète**.
|
||||
Le gain natif du candidat D reste à mesurer.
|
||||
|
||||
Les **189 tests ciblés passent**. Sept nouveaux tests couvrent : comparaison au bus octet par
|
||||
octet sur 1 144 combinaisons de plage/mode, canaris et SRAM entière, limites/overflow, pages OHCI
|
||||
non contiguës, endian des descripteurs, colonnes NAND et spare/ECC séparés, entrée aléatoire NAND,
|
||||
AES avec entrée/sortie superposées, SHA multiblocs sur les trois banques, SD/SDHC synthétique et
|
||||
protection des écritures. Ces sept tests passent aussi trois répétitions avec ordre mélangé.
|
||||
Les tests antérieurs d'AES chiffré/déchiffré, de SHA en SRAM split, de JIT/MMU et de persistance
|
||||
NAND restent dans la sélection. Les seules suppressions de fichiers des nouveaux tests concernent
|
||||
leurs images SD temporaires uniques ; aucun profil utilisateur n'est utilisé.
|
||||
|
||||
Le test natif D est préparé dans un nouveau profil depuis la graine initiale contrôlée, avec
|
||||
les mêmes fichiers initiaux que B (chemins de sortie isolés). A/B/C et les profils habituels ne
|
||||
sont pas remplacés. Build figée SHA256 :
|
||||
`1ab2746044256533185836a49e7644817f8f2d7f523c6a9c0a6199773574151c`.
|
||||
|
||||
Le premier essai D est interrompu pendant l'absence de l'utilisateur ; il n'est pas utilisé
|
||||
pour comparer la durée complète. Sa NAND de 855 883 744 octets et ses logs sont conservés dans
|
||||
`D`, avec un marqueur `Capture/interrupted.json`. À sa demande, le 19 septembre au soir, un
|
||||
nouvel essai est lancé dans `D-repeat-20260919` avec **la même build-D**, depuis les fichiers
|
||||
initiaux et la graine de NAND vérifiés à nouveau. Ses captures et repères début/fin sont distincts
|
||||
du premier essai. Aucune NAND existante n'est supprimée ni remplacée.
|
||||
|
||||
## 11. Résultat natif D répété, 19 septembre au soir
|
||||
|
||||
Le nouvel essai `D-repeat-20260919`, PID 11548, part de la graine initiale vérifiée avec la build D
|
||||
inchangée. L'utilisateur signale le départ à 18:23:04,771 UTC, puis la fin à 18:31:37,196 UTC en
|
||||
précisant qu'elle remonte peut-être à deux minutes. **Le délai entre ces deux signalements n'est
|
||||
donc pas retenu comme durée de mise à jour**, et les relevés après stabilisation sont exclus du
|
||||
bilan actif. Le premier essai D interrompu reste conservé séparément et n'entre pas dans ce bilan.
|
||||
|
||||
Les compteurs réseau atteignent leur valeur terminale au relevé de 18:29:51,774 UTC. Le journal
|
||||
atteint sa taille terminale au relevé suivant, 18:30:02,220 UTC, puis reste stable jusqu'au
|
||||
signalement. Ce repère situe la fin de l'activité observée environ **6 min 47 à 6 min 57 après le
|
||||
signalement de départ**, soit environ sept minutes. Il ne prouve pas l'instant exact d'apparition
|
||||
de l'écran de réussite ; le signalement de départ est lui aussi approximatif. Le signalement
|
||||
final arrive environ 95 secondes après le premier relevé entièrement stabilisé.
|
||||
|
||||
Pour comparer sans utiliser ce signalement final tardif, les trois essais sont recalculés sur
|
||||
les mêmes seuils échantillonnés de taille de journal : 600 Mo vers 2700 Mo, unités décimales.
|
||||
|
||||
| Portion de progression comparable | B | C | D répété |
|
||||
|---|---:|---:|---:|
|
||||
| Durée échantillonnée | 9 min 43 s | 7 min 20 s | 5 min 49 s |
|
||||
| Nombre de relevés | 54 | 42 | 34 |
|
||||
| FPS médians | 27,84 | 39,03 | 47,32 |
|
||||
| Plus bas FPS échantillonné | 7,28 | 13,17 | 18,40 |
|
||||
| Vitesse d'émulation médiane | 53,2 % | 82,2 % | 93,1 % |
|
||||
| Temps CPU du processus | 687,09 s | 511,27 s | 354,88 s |
|
||||
| Erreurs de polling NAT | 0 | 0 | 0 |
|
||||
|
||||
Sur cette portion, D demande **environ 20,7 % de temps réel et 30,6 % de temps CPU de moins que C**.
|
||||
Les seuils ne désignent pas exactement les mêmes transactions : C commence à 644 516 788 octets
|
||||
et finit à 2 728 169 380, D à 610 411 264 et 2 700 960 352. Les instantanés sont espacés d'environ
|
||||
10–11 secondes, les conditions hôte/serveur diffèrent et il ne s'agit que d'un essai par version.
|
||||
Le coût médian d'un instantané est de 697 ms dans cette portion de C et 555 ms dans D. Les
|
||||
différences observées ne constituent donc pas un effet causal précisément isolé du seul patch.
|
||||
|
||||
Sur toute la fenêtre du signalement de départ au premier plateau terminal, D a 40 relevés :
|
||||
47,64 FPS médians, 18,40 FPS au plus bas échantillonné, vitesse médiane 96,2 %, 14 relevés sous
|
||||
90 %. Les baisses persistantes se concentrent notamment vers la fin des transferts. Les valeurs
|
||||
FPS restent des instantanés, non pondérés par image. **50–60 FPS constants ne sont pas acquis.**
|
||||
|
||||
Après confirmation de fermeture, le journal complet est vérifié : **644 569 transactions**,
|
||||
2 733 507 520 octets, 165 440 pages superposées, génération 821 569, SYSCONF valide. Les neuf contenus
|
||||
du menu v514 et quinze contenus d'IOS80 v6944 correspondent aux empreintes TMD ; les autres titres
|
||||
ne sont pas contrôlés par ce vérificateur. SHA256 final :
|
||||
`4018d66489f2bfda3577a82a206abf52b152cf7a83e9c1bced0f4f4f49ec665e`.
|
||||
NAND et résultats restent dans le profil de répétition, sans suppression ni remplacement des
|
||||
essais précédents. Aucun commit/push supplémentaire n'est effectué.
|
||||
|
||||
## 12. Candidat E : lectures SRAM et écritures scalaires spécialisées
|
||||
|
||||
Le profil du dernier essai D relève notamment 116 619 902 lectures SRAM lentes et
|
||||
806 261 862 écritures SRAM. Parmi les lectures, les pages 01, 13, 1a et 02 représentent
|
||||
respectivement environ 49,99, 12,35, 11,71 et 7,53 millions d'accès. Ce sont des compteurs
|
||||
d'accès, **pas une attribution du temps CPU**. Ils motivent une optimisation ciblée,
|
||||
mesurée séparément avant de relancer une mise à jour native.
|
||||
|
||||
Le candidat E apporte quatre changements :
|
||||
|
||||
- Les lectures scalaires du JIT peuvent utiliser le chemin direct existant pour ces quatre
|
||||
pages supplémentaires. Les contrôles vivants boot0/split, trous et alignement restent actifs.
|
||||
Les transferts de listes de registres et les écritures SRAM restent sur le bus matériel.
|
||||
- Les lectures CPU alignées de 16/32 bits en SRAM résolvent une fois la banque et l'overlay ROM,
|
||||
au lieu de refaire le décodage octet par octet. Les cas timer/IPC existants gardent la priorité.
|
||||
`HW_VERSION` est lu par mot depuis son registre vivant, sans valeur forcée.
|
||||
- Un nouveau test avec une ROM non nulle révèle un défaut préexistant aux limites : une lecture
|
||||
large non alignée pouvait ignorer une partie de l'overlay boot0 ou dépasser son tableau à la
|
||||
frontière d'un miroir. Le chemin large n'est désormais retenu que si toute sa plage est
|
||||
contiguë dans la même banque ; sinon, le bus résout chaque octet.
|
||||
- Les helpers d'écriture lente du JIT sont spécialisés à la compilation pour 1, 2 ou 4 octets.
|
||||
La largeur connue de l'instruction n'est plus transmise puis testée à chaque appel. Les mêmes
|
||||
appels `ARMBus::Write8/16/32`, compteurs, conversions d'endian et effets matériels subsistent.
|
||||
Aucun timer, délai d'interruption ou engagement de persistance NAND n'est modifié.
|
||||
|
||||
La première variante limitée aux lectures accélérait les cas ciblés, mais ralentissait le
|
||||
témoin d'écriture d'environ 7 % dans les deux ordres de comparaison. Elle n'est pas la version
|
||||
retenue pour l'essai natif. La spécialisation des écritures corrige ce recul et donne les
|
||||
résultats finaux ci-dessous.
|
||||
|
||||
### Validation et mesures isolées
|
||||
|
||||
Les **192 tests de 25 suites passent** ; les 13 tests DMA/lectures SRAM passent aussi trois fois
|
||||
en ordre mélangé. Le nouveau test mémoire compare 41 472 lectures larges à l'oracle octet par
|
||||
octet, avec ROM/SRAM non nulles, changements vivants de mapping et frontières de miroirs.
|
||||
Les nouveaux tests d'écritures natives comparent JIT et interpréteur en ARM/Thumb, petit/grand
|
||||
endian et différents mappings : registres, CPSR, SRAM entière et octets voisins doivent coïncider.
|
||||
|
||||
Le banc Thumb utilise le vrai `StarletMemory`, sans firmware ni NAND utilisateur, avec 64 millions
|
||||
d'instructions et 32 millions d'accès mémoire par cas. Les builds avant/après sont alternées en
|
||||
ABBAAB puis BAABBA, neuf échantillons par cas/version dans chaque série, sur le même cœur hôte.
|
||||
Le tableau donne les médianes murales ; les registres, valeurs et compteurs sont aussi vérifiés.
|
||||
|
||||
| Cas | D, ordre 1 | E, ordre 1 | D, ordre inverse | E, ordre inverse |
|
||||
|---|---:|---:|---:|---:|
|
||||
| Lecture page 01 | 329,96 ms | 63,35 ms | 341,51 ms | 63,78 ms |
|
||||
| Lecture page 02 | 331,58 ms | 63,80 ms | 341,56 ms | 64,18 ms |
|
||||
| Lecture page 13 | 334,95 ms | 68,83 ms | 338,39 ms | 69,31 ms |
|
||||
| Lecture page 1a | 333,46 ms | 69,76 ms | 336,22 ms | 69,52 ms |
|
||||
| Lecture forcée par le bus | 318,91 ms | 258,61 ms | 323,60 ms | 260,80 ms |
|
||||
| Lecture déjà directe, témoin | 67,92 ms | 68,24 ms | 68,96 ms | 68,75 ms |
|
||||
| Écriture SRAM par le bus, témoin | 221,92 ms | 201,56 ms | 224,79 ms | 203,47 ms |
|
||||
| Lecture VERSION et mot suivant | 1417,86 ms | 874,05 ms | 1458,66 ms | 887,22 ms |
|
||||
|
||||
Les lectures nouvellement directes suppriment les 32 millions d'appels au bus de chaque cas.
|
||||
Le cas de lecture forcée et le témoin d'écriture conservent chacun leurs 32 millions d'appels.
|
||||
Le témoin de lecture déjà directe est pratiquement inchangé ; celui d'écriture demande environ
|
||||
9 % de temps en moins. La mesure VERSION inclut aussi le mot suivant, pas uniquement VERSION.
|
||||
Les conditions hôte peuvent varier ; une courte répétition de tests intervient vers la fin de
|
||||
la série inverse. Les temps CPU sont enregistrés mais leur granularité limite leur précision.
|
||||
**Ces gains synthétiques ne prédisent ni la durée totale de mise à jour ni des FPS constants.**
|
||||
|
||||
### Essai natif préparé
|
||||
|
||||
Le profil E repart des mêmes fichiers initiaux que B et de la même graine NAND, contrôlés avant
|
||||
la réécriture des seuls chemins isolés. Le journal initial comporte 125 881 transactions ;
|
||||
SYSCONF et les 24 contenus du menu/IOS80 sont vérifiés. Les profils A/B/C/D, la répétition D et
|
||||
les profils habituels sont conservés. Build E figée SHA256 :
|
||||
`9cca944ecece148b1ffa0cc77a160d5762804d79fc3817f24189e5954d9935fb`.
|
||||
Le gain natif de E reste à mesurer avec la même capture que D.
|
||||
|
||||
## 13. Résultat natif E, 19 septembre au soir
|
||||
|
||||
L'utilisateur confirme la réussite de la mise à jour E, PID 3308, à 19:17:49 UTC.
|
||||
Le départ signalé à 19:10:31 UTC est tardif par rapport aux premiers échanges réseau et
|
||||
écritures du journal. Les valeurs observées avant le signalement final atteignent leur
|
||||
dernier état à 19:17:41,598 UTC, soit environ 7 min 11 après le signalement de départ.
|
||||
Ce délai **n'est pas la durée exacte de la mise à jour**. L'activité reprend après le
|
||||
signalement final ; cette activité ultérieure est exclue du bilan de mise à jour.
|
||||
|
||||
La comparaison principale reprend les mêmes seuils échantillonnés de journal que pour D :
|
||||
|
||||
| Portion de journal 600 Mo vers 2700 Mo | D répété | E |
|
||||
|---|---:|---:|
|
||||
| Durée échantillonnée | 348,91 s | 350,34 s |
|
||||
| Nombre de relevés | 34 | 34 |
|
||||
| FPS médians | 47,32 | 48,70 |
|
||||
| Plus bas FPS échantillonné | 18,40 | 20,13 |
|
||||
| Vitesse d'émulation médiane | 93,05 % | 95,25 % |
|
||||
| Relevés sous 90 % de vitesse | 14 | 16 |
|
||||
| Temps CPU du processus | 354,88 s | 353,86 s |
|
||||
| Coût médian d'un instantané | 555,37 ms | 597,96 ms |
|
||||
| Erreurs de polling NAT | 0 | 0 |
|
||||
|
||||
Le temps réel augmente de 0,4 % et le temps CPU diminue de 0,3 % : **aucune accélération
|
||||
globale convaincante n'est démontrée**. La légère amélioration des FPS médians et minimaux
|
||||
ne suffit pas à établir un gain reproductible. Les seuils sont franchis à des transactions
|
||||
différentes : D couvre 610 411 264 à 2 700 960 352 octets, E 655 167 424 à 2 732 944 480.
|
||||
Les conditions hôte/serveur diffèrent, les mesures restent espacées d'environ 10–11 secondes,
|
||||
et il ne s'agit que d'un essai par version. Les gains du banc ciblé ne se traduisent donc
|
||||
pas par un nouveau gain comparable à C vers D dans cet essai natif.
|
||||
|
||||
La fenêtre du signalement de départ au dernier état pré-signalement contient 41 relevés :
|
||||
49,25 FPS médians, 20,13 au minimum, vitesse médiane 96,6 %, 16 relevés sous 90 % et 409,77 s
|
||||
de temps CPU. Les relevés après le signalement final ne sont pas inclus. Le journal atteint
|
||||
2 733 507 520 octets avant ce signalement puis continue à évoluer lors de l'activité suivante.
|
||||
Après confirmation de fermeture, la capture se termine à 19:52:07,295 UTC. Le journal final
|
||||
de **2 798 712 064 octets contient 659 844 transactions valides**, 165 568 pages superposées
|
||||
et une génération de système de fichiers de 821 657. SYSCONF est valide ; les neuf contenus
|
||||
du menu v514 et quinze contenus d'IOS80 v6944 correspondent aux empreintes TMD. Les autres
|
||||
titres ne sont pas contrôlés par ce vérificateur. Empreinte SHA256 finale :
|
||||
`5002e06eb368fbc9b55c4e7d1c377391c734a2ccdad8a7ea7df3b3dac352fb16`.
|
||||
|
||||
Le préfixe enregistré juste avant le signalement de fin est également vérifié en lecture
|
||||
seule, **sans tronquer ni restaurer le journal** : 2 733 507 520 octets, 644 569 transactions,
|
||||
165 440 pages et génération 821 569. SYSCONF et les mêmes 24 contenus sont valides. Son SHA256
|
||||
est `bae4e8b6f7060139f21a1968c67a5d38199ee96109e873b3467ae59d15f37d17`.
|
||||
La différence avec le journal final provient des écritures ultérieures, exclues du bilan de
|
||||
mise à jour. L'ensemble reste conservé dans le profil E ; aucune NAND ni build antérieure
|
||||
n'est remplacée. Aucun commit/push supplémentaire n'est effectué.
|
||||
|
||||
## 14. Candidat F : profilage mémoire détaillé à la demande
|
||||
|
||||
Après E, la durée de mise à jour ne baisse pas de façon convaincante. Le candidat F isole
|
||||
donc le coût du diagnostic, sans modifier les transactions invitées. Les chemins mémoire
|
||||
lents incrémentaient systématiquement plusieurs compteurs de région/page, et alimentaient
|
||||
une table de hachage d'adresses tous les 256 accès, même en usage normal.
|
||||
|
||||
`WiiStarletJITMemoryProfiling` est désormais un réglage hôte optionnel, désactivé par défaut.
|
||||
Le choix est fixé à la construction du cœur et le JIT sélectionne un helper spécialisé lors
|
||||
de la génération de code : aucun test dynamique du réglage n'est ajouté par accès. Le mode
|
||||
normal conserve les **totaux** de lectures/écritures lentes et les compteurs d'instructions ;
|
||||
il évite la classification, les compteurs détaillés et la table d'adresses. Le mode diagnostic
|
||||
les conserve. Les logs identifient explicitement `memory-profile=false` pour que des compteurs
|
||||
détaillés indisponibles ne soient pas interprétés comme une absence d'accès.
|
||||
|
||||
Le script de lancement expose `-ProfileJitMemory`. Le réglage n'est pas sérialisé dans l'état
|
||||
invité, demeure identique après reset et rechargement des caches, et ne modifie ni endian,
|
||||
protection boot0, mapping SRAM, interruptions, horloges ni persistance NAND. Les lectures et
|
||||
écritures continuent à appeler les mêmes méthodes du bus. Les classements de pages/adresses
|
||||
ne sont calculés dans les logs que lorsque le profilage détaillé est activé.
|
||||
|
||||
### Comparaison dans un même exécutable
|
||||
|
||||
Le banc reprend le vrai bus `StarletMemory`, sans firmware ni profil utilisateur. Un **même
|
||||
exécutable figé** est lancé avec le profilage activé/désactivé, en ordre ON/OFF/OFF/ON/ON/OFF,
|
||||
puis dans l'ordre inverse. Chaque série comporte neuf échantillons par mode/cas, trois tours
|
||||
par processus, affinité identique et compilation initiale exclue. Chaque mesure exécute
|
||||
64 millions d'instructions et 32 millions d'accès ; les valeurs finales et totaux d'accès
|
||||
sont vérifiés. Aucun build ni test unitaire ne tourne pendant ces deux séries.
|
||||
|
||||
| Cas, médianes murales | ON, ordre 1 | OFF, ordre 1 | ON, inverse | OFF, inverse |
|
||||
|---|---:|---:|---:|---:|
|
||||
| Lecture SRAM déjà directe, page 01 | 58,85 ms | 59,01 ms | 59,92 ms | 59,15 ms |
|
||||
| Lecture SRAM forcée sur le bus | 256,89 ms | 234,06 ms | 262,07 ms | 234,36 ms |
|
||||
| Lecture SRAM déjà directe, page 14 | 64,12 ms | 63,94 ms | 64,90 ms | 64,15 ms |
|
||||
| Écriture SRAM sur le bus | 202,66 ms | 167,61 ms | 205,49 ms | 168,06 ms |
|
||||
| Lecture VERSION et mot suivant | 964,43 ms | 919,85 ms | 968,57 ms | 928,59 ms |
|
||||
|
||||
Le coût diminue d'environ **17–18 % pour les écritures SRAM lentes**, **9–11 % pour les
|
||||
lectures SRAM forcées sur le bus** et **4–5 % sur le cas MMIO**. Les témoins déjà directs
|
||||
restent proches. Les temps CPU sont enregistrés, avec la limite habituelle de granularité.
|
||||
La variabilité hôte demeure ; ces chiffres comparent les deux modes du candidat F dans le
|
||||
même binaire, pas des temps historiques de builds différents. **Ils ne démontrent pas encore
|
||||
un gain de durée sur une mise à jour native.**
|
||||
|
||||
### Validation
|
||||
|
||||
Les **195 tests de 27 suites passent**, couvrant Starlet, IPC, lecteurs TMD, systèmes de
|
||||
fichiers et CoreTiming. Les quatre tests de lectures/écritures SRAM réelles sont désormais
|
||||
paramétrés pour tourner avec et sans profilage : ARM/Thumb, deux endiannesses, mappings
|
||||
vivants, frontières et invalidations TLB restent comparés à l'interpréteur. Un nouveau test
|
||||
vérifie dans les deux modes les résultats SRAM/MMIO, les totaux exacts de 256 lectures et
|
||||
256 écritures par phase, l'échantillonnage détaillé et son absence lorsqu'il est désactivé,
|
||||
puis recommence après reset. Les 20 tests ciblés SRAM/DMA/IPC passent aussi trois répétitions
|
||||
dans un ordre mélangé. Deux benchmarks historiques restent désactivés.
|
||||
|
||||
Build compilée SHA256 :
|
||||
`bdfb27dbf23065c7894640323f615220140f6cda2fe250814cb59cc22f858a9d`.
|
||||
Exécutable du banc ON/OFF SHA256 :
|
||||
`0e20fda45f75464cba4414c4884ddca13a77c0adc221a91622f7a45aa18692a3`.
|
||||
La validation native reste à faire. Au moment de la préparation, environ 4,2 Go restent sur
|
||||
C:, insuffisants pour un nouveau profil depuis la graine, la croissance prévue du journal
|
||||
et la réserve de sécurité du protocole. Aucun essai natif F n'est lancé et aucune ancienne
|
||||
NAND n'est supprimée pour contourner ce manque d'espace.
|
||||
|
||||
L'espace est ensuite libéré indépendamment du test : environ 81 Gio sont disponibles avant
|
||||
préparation. À la demande de l'utilisateur, le profil F est créé depuis les mêmes fichiers
|
||||
initiaux vérifiés que B ; les chemins de sortie sont les seules modifications du profil.
|
||||
Le journal initial de 533 705 344 octets, ses 125 881 transactions, SYSCONF et les 24 contenus
|
||||
menu/IOS80 sont vérifiés. La build F et ses symboles sont figés avec les empreintes testées.
|
||||
L'instance F démarre le 19 septembre à **21:17:04 UTC**, PID 32008, capture PID 20080, avec
|
||||
le profilage mémoire détaillé désactivé. Aucun résultat de performance natif F n'est encore
|
||||
conclu ; les signalements de départ et fin de mise à jour sont attendus dans `F/Capture`.
|
||||
|
||||
À **21:21:25 UTC**, le collecteur est remplacé (PID 33736) sans arrêter Dolphin :
|
||||
le lecteur initial échoue sur l'annotation facultative d'une adresse interne du JIT.
|
||||
Le lecteur local `LiveStateF` signale explicitement `JIT_METADATA_UNAVAILABLE` et poursuit
|
||||
les lectures obligatoires FPS/CPU, E/S, NAT et registres de contrôle AES. La cause exacte
|
||||
de l'adresse invalide dans les symboles incrémentaux n'est pas établie. Ce changement
|
||||
concerne uniquement l'observateur, pas l'émulation ni les compteurs du candidat.
|
||||
Les nouvelles captures terminent avec `SNAPSHOT_EXIT=0` ; les anciennes captures en échec
|
||||
sont conservées, mais doivent être exclues de la comparaison native. Les mesures valides
|
||||
sont dans `metrics-20260919-232125-32008.txt`, avec le coût de chaque capture enregistré.
|
||||
`reader-fix.json` et `launch-before-reader-fix.json` conservent la trace du remplacement.
|
||||
En attente du lancement de la mise à jour, les lectures montrent environ 50 FPS à vitesse
|
||||
100 % ; cela ne mesure pas encore le gain pendant une mise à jour.
|
||||
|
||||
### Résultat natif F : succès fonctionnel, gain non validé
|
||||
|
||||
L'utilisateur signale le départ, relevé à **21:26:45 UTC**, puis la réussite, relevée à
|
||||
**21:35:53 UTC**. Ces repères ne sont pas les instants exacts de clic ou d'affichage ;
|
||||
l'activité avait déjà commencé avant le signalement du départ. La comparaison conserve
|
||||
les mêmes seuils échantillonnés du journal (600 à 2 700 Mo), sans inclure l'activité après
|
||||
le signalement de fin.
|
||||
|
||||
| Mesure sur ces seuils | D répété | E | F |
|
||||
|---|---:|---:|---:|
|
||||
| Temps mural | 348,91 s | 350,34 s | 442,04 s |
|
||||
| Temps CPU du processus | 354,88 s | 353,86 s | 522,23 s |
|
||||
| FPS médian des échantillons | 47,32 | 48,70 | 40,985 |
|
||||
| FPS minimal échantillonné | 18,40 | 20,13 | 11,08 |
|
||||
| Vitesse médiane | 93,05 % | 95,25 % | 80,3 % |
|
||||
| Échantillons sous 90 % | 14/34 | 16/34 | 25/42 |
|
||||
| Coût médian d'une capture | 555,37 ms | 597,96 ms | 749,90 ms |
|
||||
| Erreurs du polling NAT supplémentaires | 0 | 0 | 0 |
|
||||
|
||||
F prend **26,2 % de temps mural et 47,6 % de temps CPU supplémentaires par rapport à E**.
|
||||
Les quatre sous-plages de progression sont également plus lentes. Ce résultat ne valide
|
||||
donc pas l'optimisation sur la mise à jour réelle, malgré le gain des microbenchmarks.
|
||||
Il ne suffit pas à attribuer la régression à la désactivation des compteurs : les essais
|
||||
ne sont pas alternés dans les mêmes conditions hôte/serveur, et les seuils ne correspondent
|
||||
pas exactement aux mêmes transactions. Le coût du lecteur est aussi plus élevé ; les
|
||||
compteurs CPU du processus Dolphin n'incluent pas le CPU du lecteur externe.
|
||||
L'absence d'erreur de polling NAT n'exclut pas une attente du serveur.
|
||||
|
||||
La prochaine expérience utile serait une comparaison native ON/OFF alternée du **même
|
||||
binaire F**, depuis la même graine, avec un lecteur fiable commun et des conditions hôte
|
||||
relevées. Elle n'est pas lancée automatiquement à la clôture de F. Aucun correctif
|
||||
supplémentaire de l'émulation n'est appliqué pendant cet essai.
|
||||
|
||||
Après fermeture demandée à l'utilisateur, le collecteur se termine à **21:37:36 UTC**.
|
||||
La dernière capture échoue pendant la disparition du processus et est exclue des calculs.
|
||||
Le journal final est conservé : **2 783 208 736 octets**, **656 226 transactions valides**,
|
||||
165 440 pages superposées, génération 821638, SYSCONF valide. Les 24 contenus du menu v514
|
||||
et d'IOS80 v6944 correspondent à leurs empreintes TMD ; les autres titres ne sont pas
|
||||
vérifiés par ce contrôle. Empreinte SHA256 du journal :
|
||||
`6d0341773c613aab63194153f44541b12d75541d0cab53b94b2c014544e9aab0`.
|
||||
Les anciennes NAND et le profil habituel sont inchangés.
|
||||
|
||||
## Reproduction / fichiers de travail
|
||||
|
||||
- `.starlet-profile/StudyUpdateJournal.py` : analyse du journal réel en lecture seule.
|
||||
- `.starlet-profile/update-journal-study-20260913.json` : totaux et vérification des transactions.
|
||||
- `.starlet-profile/UpdateStudyBench.cpp` et `BuildUpdateStudy.ps1` : banc d'essai séparé.
|
||||
- `.starlet-profile/ARMJitStudy.cpp` : copie expérimentale du JIT, pas le fichier de production.
|
||||
- `.starlet-profile/update-study-bench-20260913.txt` : première comparaison des journaux et des accès.
|
||||
- `.starlet-profile/update-study-arm-ab-summary-20260913.json` : échantillons A/B d'écriture.
|
||||
- `.starlet-profile/update-study-tests-with-nat-20260913.txt` : résultat des 176 tests du prototype ARM.
|
||||
- `.starlet-profile/CompareSRAMReads.ps1` et `sram-read-ab-samples.json` : comparaison des lectures.
|
||||
- `.starlet-profile/sram-read-all-tests.txt` : les 179 tests après extension des lectures.
|
||||
- `.starlet-profile/PrepareUpdateAB.ps1`, `RunUpdateAB.ps1`, `CaptureWiiUpdate.ps1` : essais isolés.
|
||||
- `.starlet_update_ab_20260913/manifest.json` : provenance, empreintes des deux builds et des NAND.
|
||||
- `.starlet_update_ab_20260913/A/Capture` et `B/Capture` : mesures de chaque exécution.
|
||||
- `.starlet-profile/SummarizeUpdateCapture.ps1` : synthèse des fenêtres horodatées.
|
||||
- `.starlet_update_ab_20260913/journal-progress-comparison.json` : repères automatiques de progression.
|
||||
- `.starlet-profile/CompareBusWrites20260919.ps1` : comparaisons alternées du nouveau bus.
|
||||
- `.starlet-profile/bus-write-ab-samples-20260919.json` et `bus-write-ab-samples-20260919-repeat.json` : mesures brutes.
|
||||
- `.starlet-profile/tests-bus-writes-final-20260919.log` : validation finale des 182 tests.
|
||||
- `.starlet-profile/PrepareUpdateC20260919.ps1`, `.starlet_update_ab_20260913/manifest-C-20260919.json`
|
||||
et `C/Capture` : provenance et enregistrement du troisième essai natif.
|
||||
- `.starlet-profile/DMAStudy.cpp`, `BuildDMAStudy.ps1`, `DMABefore20260919.exe`,
|
||||
`DMAAfter20260919.exe` : banc de copie MMIO et exécutables comparés.
|
||||
- `.starlet-profile/dma-ab-samples-20260919.json`, `dma-ab-summary-20260919.json` : 108 mesures DMA.
|
||||
- `.starlet-profile/tests-dma-final-20260919.log`, `tests-dma-repeat-20260919.log` : tests du candidat D.
|
||||
- `.starlet-profile/PrepareUpdateD20260919.ps1`, `.starlet_update_ab_20260913/manifest-D-20260919.json`
|
||||
et `D/Capture` : préparation et mesures du quatrième essai natif.
|
||||
- `.starlet-profile/PrepareUpdateDRepeat20260919.ps1`, `AnalyzeUpdateDRepeat20260919.ps1` et
|
||||
`.starlet_update_ab_20260913/D-repeat-20260919/Capture` : répétition depuis la graine, repères
|
||||
d'activité, comparaison des seuils, vérification NAND et compte rendu final `completion.json`.
|
||||
|
||||
- `.starlet-profile/ReadStudyE.cpp`, `BuildReadStudyE.ps1`, `CompareReadStudyESized.ps1` :
|
||||
banc réel de lectures/écritures scalaires et comparaison alternée de D/E.
|
||||
- `.starlet-profile/read-e-sized-ab-samples-20260919.json` et
|
||||
`read-e-sized-ab-samples-20260919-reverse.json` : mesures finales dans les deux ordres.
|
||||
- `.starlet-profile/tests-E-sized-final-20260919.log`, `tests-E-sized-repeat-20260919.log` :
|
||||
tests complets et répétitions ciblées du candidat E.
|
||||
- `.starlet-profile/PrepareUpdateE20260919.ps1`, `.starlet_update_ab_20260913/manifest-E-20260919.json`
|
||||
et `E/Capture` : provenance, profil et captures du cinquième essai natif.
|
||||
- `.starlet-profile/AnalyzeUpdateE20260919.ps1`, `E/Capture/completion-report.json`,
|
||||
`journal-progress-comparison.json`, `delta-vs-D.json` : repère de réussite et bilan natif E.
|
||||
- `E/Capture/final-journal-verification.txt`, `update-completion-prefix-verification.txt`
|
||||
et `completion.json` : contrôles après fermeture, empreintes et compte rendu final E.
|
||||
- `.starlet-profile/ReadStudyF.cpp`, `ReadStudyF20260919.exe`, `CompareMemoryProfileF.ps1` :
|
||||
même banc réel avec choix ON/OFF au démarrage, sans changer de binaire.
|
||||
- `.starlet-profile/memory-profile-F-20260919.json`, `memory-profile-F-20260919-reverse.json` :
|
||||
180 mesures brutes du candidat F.
|
||||
- `.starlet-profile/tests-F-expanded-20260919.log`, `tests-F-repeat-20260919.log` et
|
||||
`build-F-memory-profile-20260919.log` : tests, répétitions et compilation.
|
||||
- `.starlet-profile/PrepareUpdateF20260919.ps1`, `.starlet_update_ab_20260913/manifest-F-20260919.json`
|
||||
et `F/Capture/launch.json` : provenance et lancement du sixième essai natif isolé.
|
||||
- `.starlet-profile/AnalyzeUpdateF20260919.ps1`, `F/Capture/report-window-summary.json`,
|
||||
`journal-progress-comparison.json`, `journal-progress-phases.json`, `deltas-vs-D-E.json` :
|
||||
comparaison native, limitée aux captures complètes du lecteur corrigé et à la fenêtre du test.
|
||||
- `F/Capture/completion-report.json`, `final-journal-verification.txt`,
|
||||
`update-completion-prefix-verification.txt`, `completion.json` : fin signalée et contrôles NAND.
|
||||
|
||||
Les prototypes et données de mesure restent dans les répertoires locaux ignorés.
|
||||
Ce rapport est la seule nouvelle documentation destinée au dépôt ; les modifications
|
||||
préexistantes du correctif d'appairage Wiimote sont conservées.
|
||||
Reference in new issue
Block a user