[FIX] imbrication : le coût d'un vCPU dépend de la profondeur de l'étage
Amorçage du quatrième étage, mesuré sur deux descentes complètes : 1 664 s à 2 vCPU, 15 608 s à 3. Un seul vCPU de plus, ×9,4. Aux étages 2 et 3 le même vCPU ne coûte RIEN — ssh en 37 s et 93 s, comme à deux. Le « gel » observé à 8 et 12 vCPU n'est probablement pas autre chose que cette courbe poussée assez loin : 1 664 × 9,4 par vCPU dépasse vite toute patience, et un RIP immobile à cinq minutes d'intervalle ne s'en distingue pas. D'où un SEUIL de profondeur au lieu d'une largeur uniforme. Le troisième vCPU reste aux étages 2 et 3, où il est gratuit et où il enlève le surengagement qui affamait l'installation de l'étage 4 — celle-ci ne finissait pas avec un parent à 2 vCPU, elle progresse avec un parent à 3. À partir du quatrième étage, le strict minimum. La combinaison ainsi obtenue — parent 3, enfant 2 — n'a jamais été mesurée : les deux essais étaient (2, 2) et (3, 3). --- EN --- Fourth-level boot, measured on two full descents: 1,664 s at 2 vCPU, 15,608 s at 3. One more vCPU, ×9.4. At levels 2 and 3 that same vCPU costs NOTHING — ssh in 37 s and 93 s, same as at two. The "freeze" seen at 8 and 12 vCPU is most likely nothing but this curve taken far enough: 1,664 × 9.4 per vCPU quickly exceeds any patience, and a static RIP five minutes apart is indistinguishable from it. Hence a depth THRESHOLD instead of a uniform width. The third vCPU stays at levels 2 and 3, where it is free and where it removes the overcommit that starved level 4's install — which never finished with a 2-vCPU parent and does progress with a 3-vCPU one. From the fourth level down, the strict minimum. The resulting combination — parent 3, child 2 — has never been measured: the two attempts were (2, 2) and (3, 3). Assisted-by: claude-opus-5 (cherry picked from commit 9a5583a4b9461a087d161775764c560c82e0609e)
This commit is contained in:
parent
b2b3f36026
commit
30399b4559
2 changed files with 60 additions and 15 deletions
|
|
@ -101,14 +101,25 @@ DISQUE_MIN_GO = 15
|
|||
# Le plus profond : deux, le seul chiffre dont on ait la preuve qu'il démarre
|
||||
# au quatrième étage.
|
||||
VCPU_IMBRIQUE = 2
|
||||
# Les étages imbriqués intermédiaires : un de plus, pour héberger leur enfant
|
||||
# Les étages imbriqués PEU PROFONDS : un de plus, pour héberger leur enfant
|
||||
# sans être aussi étroits que lui. Deux hébergeant deux, c'est cent pour cent
|
||||
# de surengagement — et l'installation de l'étage 4 dépassait alors 2 h 50
|
||||
# contre 793 s pour l'étage 3.
|
||||
#
|
||||
# Trois est une HYPOTHÈSE : on a la preuve que deux démarre au quatrième étage
|
||||
# et que huit gèle, rien entre les deux. C'est la descente qui tranchera.
|
||||
# « Peu profonds », et c'est la mesure qui l'impose. Ce troisième vCPU ne coûte
|
||||
# RIEN aux étages 2 et 3 — leur ssh répond en 37 s et 93 s, comme à deux vCPU —
|
||||
# et il coûte tout au quatrième : 15 608 s, soit 4 h 20, contre 1 664 s à deux
|
||||
# vCPU. Un seul vCPU de plus, l'amorçage multiplié par 9,4.
|
||||
VCPU_INTERMEDIAIRE = 3
|
||||
# Le premier étage qui doit rester au strict minimum.
|
||||
#
|
||||
# Amorçage du quatrième étage, mesuré : 1 664 s à 2 vCPU, 15 608 s à 3, jamais
|
||||
# à 8 ni à 12 — même RIP à cinq minutes d'intervalle. Le « gel » observé à 8 et
|
||||
# 12 n'est probablement pas autre chose que cette courbe poussée assez loin :
|
||||
# 1 664 × 9,4 par vCPU supplémentaire dépasse vite toute patience.
|
||||
#
|
||||
# Aux étages 2 et 3, la même largeur ne coûte rien. Le seuil est donc là.
|
||||
SEUIL_ETROIT = 4
|
||||
# Le premier étage tourne sur le MÉTAL : aucun risque de gel, et son amorçage
|
||||
# est rapide — onze vCPU y ont démarré en 42 s. Il n'a pourtant qu'un enfant à
|
||||
# trois vCPU à servir ; quatre suffisent, et laissent la machine physique aux
|
||||
|
|
@ -178,8 +189,9 @@ def nesting_plan(
|
|||
étages tienne : la cible du bas, plus un surcoût par étage au-dessus.
|
||||
|
||||
Le processeur n'en fait PAS partie de la même façon : il ne croît
|
||||
pas avec la profondeur, puisque tout étage imbriqué reste étroit. Le
|
||||
premier étage demande VCPU_METAL, quelle que soit la profondeur.
|
||||
pas avec la profondeur — il DÉCROÎT, et se stabilise à
|
||||
VCPU_IMBRIQUE dès SEUIL_ETROIT. Le premier étage demande VCPU_METAL,
|
||||
quelle que soit la profondeur.
|
||||
"""
|
||||
return (
|
||||
PVE_RAM_CIBLE_MO + (d - 1) * PVE_RAM_MO,
|
||||
|
|
@ -212,15 +224,21 @@ def nesting_plan(
|
|||
niveaux = [
|
||||
{
|
||||
"niveau": niveau,
|
||||
# Trois largeurs, et aucune ne dépend de la profondeur : le
|
||||
# métal en premier, le fond au plus étroit, les intermédiaires
|
||||
# juste assez larges pour héberger leur enfant.
|
||||
# Le métal peut être large ; un étage imbriqué peu profond
|
||||
# gagne son troisième vCPU pour héberger son enfant sans
|
||||
# surengagement ; à partir de SEUIL_ETROIT, le strict minimum,
|
||||
# parce que là ce troisième vCPU multiplie l'amorçage par 9,4.
|
||||
#
|
||||
# L'étage juste AU-DESSUS du seuil garde donc trois quand son
|
||||
# enfant en a deux : c'est le seul endroit de la descente où le
|
||||
# surengagement disparaît, et c'est celui qui compte, puisque
|
||||
# l'étage 4 est le premier dont l'installation s'effondrait.
|
||||
"vcpu": (
|
||||
VCPU_METAL
|
||||
if niveau == 1
|
||||
else (
|
||||
VCPU_IMBRIQUE
|
||||
if niveau == atteignable
|
||||
if niveau >= SEUIL_ETROIT
|
||||
else VCPU_INTERMEDIAIRE
|
||||
)
|
||||
),
|
||||
|
|
|
|||
|
|
@ -83,14 +83,41 @@ class TestLePlanDesEtages(unittest.TestCase):
|
|||
)
|
||||
|
||||
def test_the_three_widths_are_where_they_belong(self):
|
||||
"""Le coût d'un vCPU dépend de la PROFONDEUR de l'étage, pas d'une
|
||||
largeur absolue.
|
||||
|
||||
Mesuré : le troisième vCPU ne coûte rien aux étages 2 et 3 — ssh en
|
||||
37 s et 93 s, comme à deux vCPU — et coûte 4 h 20 au quatrième, contre
|
||||
1 664 s à deux. Un seul vCPU de plus, l'amorçage ×9,4."""
|
||||
niveaux = nesting.nesting_plan(6, **self.HOTE)["niveaux"]
|
||||
largeurs = {n["niveau"]: n["vcpu"] for n in niveaux}
|
||||
# Le métal : aucun risque de gel, onze vCPU y ont démarré en 42 s.
|
||||
self.assertEqual(niveaux[0]["vcpu"], nesting.VCPU_METAL)
|
||||
# Le fond : le seul chiffre dont on ait la preuve qu'il démarre au
|
||||
# quatrième étage.
|
||||
self.assertEqual(niveaux[-1]["vcpu"], nesting.VCPU_IMBRIQUE)
|
||||
for n in niveaux[1:-1]:
|
||||
self.assertEqual(n["vcpu"], nesting.VCPU_INTERMEDIAIRE)
|
||||
self.assertEqual(largeurs[1], nesting.VCPU_METAL)
|
||||
# Peu profonds : le troisième vCPU est gratuit, et il enlève le
|
||||
# surengagement là où l'installation s'effondrait.
|
||||
for niveau in range(2, nesting.SEUIL_ETROIT):
|
||||
self.assertEqual(
|
||||
largeurs[niveau], nesting.VCPU_INTERMEDIAIRE, f"étage {niveau}"
|
||||
)
|
||||
# À partir du seuil : le strict minimum, sans exception.
|
||||
for niveau in range(nesting.SEUIL_ETROIT, 7):
|
||||
self.assertEqual(
|
||||
largeurs[niveau], nesting.VCPU_IMBRIQUE, f"étage {niveau}"
|
||||
)
|
||||
|
||||
def test_the_level_above_the_threshold_keeps_its_headroom(self):
|
||||
"""C'est le seul endroit de la descente où le surengagement disparaît,
|
||||
et c'est celui qui compte : l'étage 4 est le premier dont
|
||||
l'installation s'effondrait, faute d'un parent plus large que lui.
|
||||
|
||||
Les deux combinaisons mesurées étaient (parent 2, enfant 2) — démarre
|
||||
en 1 664 s puis l'installation ne finit pas — et (parent 3, enfant 3) —
|
||||
démarre en 15 608 s. Celle-ci est (parent 3, enfant 2)."""
|
||||
niveaux = nesting.nesting_plan(6, **self.HOTE)["niveaux"]
|
||||
largeurs = {n["niveau"]: n["vcpu"] for n in niveaux}
|
||||
parent = largeurs[nesting.SEUIL_ETROIT - 1]
|
||||
enfant = largeurs[nesting.SEUIL_ETROIT]
|
||||
self.assertGreater(parent, enfant)
|
||||
|
||||
def test_a_single_level_descent_runs_on_metal(self):
|
||||
niveaux = nesting.nesting_plan(1, **self.HOTE)["niveaux"]
|
||||
|
|
|
|||
Loading…
Reference in a new issue