Question gouvernante : Comment garantir un chargement asynchrone par morceaux sous contrainte stricte de budget VRAM sans saccade (frame stutter) ?
Statut : cycle, budget, fallback, générations et campagne bornée implémentés. La campagne WebGPU reste not-run jusqu'au branchement du chargeur physique dans bench/main.ts.
Cold ──► Loading ──► Partially Resident ──► Fully Resident ──► Eviction ──► Re-request
Chaque transition est instrumentée et mesurée séparément.
| Palier | Fraction demandée |
|---|---|
| G-10 | 10 % |
| G-25 | 25 % |
| G-50 | 50 % |
| G-100 | 100 % |
| Métrique | Définition |
|---|---|
residentBytes |
Mémoire résidente (octets) |
uploadedBytes |
Volume chargé cette trame (octets) |
evictedBytes |
Volume évincé cette trame (octets) |
uploadTimeMs |
Temps de upload (ms) |
frameTimeMs |
Temps de frame (ms) |
stalls |
Nombre de frames bloquées sur l'upload |
| Verdict | Condition |
|---|---|
INTEGRATE |
stalls == 0 sur les 4 paliers et frameTimeMs < budget contractuel |
REJECT |
stalls > N/10 sur n'importe quel palier (saccade persistante) |
WATCHLIST |
Gain net démontré seulement à G-10 (fraction faible) — technique utile mais sensible à la charge |
- Streaming multi-GPU / partitionnement.
- Évacuation LRU vs. LRU + pré-fetch : le banc choisit une politique, pas les tester toutes.
- Streaming de textures : non couvert (watchlist README).
runStreamingCampaign reçoit les définitions de pages, une trajectoire de frames déterministe, les budgets, un chargeur asynchrone, un AbortSignal et un callback de progression. Chaque frame rapporte octets demandés/acceptés/évincés et défauts de résidence. Le gestionnaire refuse une page plus grande que le budget ou une éviction qui exigerait de supprimer une racine épinglée.