Files
dolphin/docs/Wii_LLE_Update_Performance_Study_2026-09-13.md
T
Yaya48 c230971f07 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.
2026-09-23 13:30:17 +02:00

54 KiB
Raw Blame History

É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. 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.