From 8ff6ae7b3a767bc2478173b74196936df254d2f8 Mon Sep 17 00:00:00 2001 From: Sergio Date: Tue, 8 Sep 2026 14:57:26 +0000 Subject: [PATCH] =?UTF-8?q?pgo:=20el=20control=20que=20faltaba=20=E2=80=94?= =?UTF-8?q?=20el=20arranque=20eran=2016=20s=20y=20dilu=C3=ADa=20todos=20lo?= =?UTF-8?q?s=20porcentajes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El banco medía el ciclo COMPLETO del proceso (arrancar → renderizar → capturar → salir) y nunca se midió cuánto de eso era arranque. Con una página vacía como control, y las 4 cargas × 2 variantes en UNA sola sesión intercalada (restar entre corridas de días distintos no vale: la misma variante deriva ~1%): maquetación trabajo 7281 → 4744 ms -34,8% (publicado: -10,9%) carga ajena trabajo 4550 → 4634 ms +1,8% = cero, y es buena señal SunSpider trabajo -34 → -6 ms bajo el ruido Dos correcciones al documento: 1. El -10,9% es correcto para el ciclo completo pero se leía como 'firefox 11% más rápido'. Sobre el trabajo de la página el PGO rinde -34,8%: tres veces más. El error subestimaba el propio resultado. 2. La explicación que di del SunSpider era aire. Su trabajo mide -34 ms, NEGATIVO: la página con el benchmark tardó menos que la vacía. No había nada que medir, y yo le colgué encima una teoría sobre el JIT. La teoría puede ser cierta; esta medición nunca la probó. Las tablas viejas se dejan sin retocar, con un aviso arriba: el error de método enseña más que el número corregido. Todo el rigor estadístico estaba puesto sobre una cantidad que no era la que yo creía medir, y ninguna repetición lo habría revelado — sólo un control, que costó siete corridas de una página vacía. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2 --- docs/26-atuq-envoltorio-gecko.md | 56 ++ docs/evidencia/pgo-banco-final-2026-09-08.txt | 22 + scripts/diagnostico/ajena.html | 48 ++ scripts/diagnostico/banco-pgo-final.sh | 45 ++ scripts/diagnostico/del-corpus.html | 490 ++++++++++++++++++ scripts/diagnostico/fuera-del-corpus.html | 20 + scripts/diagnostico/vacia.html | 1 + 7 files changed, 682 insertions(+) create mode 100644 docs/evidencia/pgo-banco-final-2026-09-08.txt create mode 100644 scripts/diagnostico/ajena.html create mode 100755 scripts/diagnostico/banco-pgo-final.sh create mode 100644 scripts/diagnostico/del-corpus.html create mode 100644 scripts/diagnostico/fuera-del-corpus.html create mode 100644 scripts/diagnostico/vacia.html diff --git a/docs/26-atuq-envoltorio-gecko.md b/docs/26-atuq-envoltorio-gecko.md index 14248746..d1b42195 100644 --- a/docs/26-atuq-envoltorio-gecko.md +++ b/docs/26-atuq-envoltorio-gecko.md @@ -227,6 +227,11 @@ llevan `-fprofile-use`**, el configure encontró `llvm-profdata`, y no hay ni un no cuadre. `libxul.so` pasa de 226.078.752 a 227.802.816 bytes, consistente con inlining de caminos calientes. Es evidencia de build, no de artefacto, y conviene decirlo así. +⚠⚠ **LEER PRIMERO: LOS PORCENTAJES DE LAS TRES TABLAS QUE SIGUEN ESTÁN DILUIDOS Y NO SON LO +QUE PARECEN.** Miden el ciclo completo del proceso, del que **~16 s son arranque**. La corrección, +con el control que faltaba, está más abajo en «EL CONTROL QUE FALTABA». Se dejan tal cual se +publicaron, sin retocar, porque el error de método es el que enseña. + **LA GANANCIA, MEDIDA (2026-09-07).** Mismo rootfs, mismo script, corridas INTERCALADAS A/B/A/B para que la deriva de carga afecte a las dos, mediana de 7, calentamiento descartado. Lo único que cambia entre variantes es un `--ro-bind` de `/usr/lib/firefox`. @@ -325,6 +330,57 @@ la página de medición, así que el parentesco con lo que ahora se entrena es m −11,4 % es real para ESTA carga; generalizarlo a «cualquier página» sería justo el error que el propio corpus de Mozilla cometía al revés. +## EL CONTROL QUE FALTABA: el arranque eran 16 s, y sin restarlo ningún porcentaje significa nada (2026-09-08) + +Todo lo de arriba mide **el ciclo completo del proceso**: arrancar firefox, renderizar, capturar el +PNG y salir. Nunca se midió cuánto de eso era la página. Faltaba el control más barato posible —una +página VACÍA— y con él las cifras publicadas se leen distinto: + +| carga | total sin PGO | total con PGO | **trabajo** sin → con | mejora del TRABAJO | +|---|---|---|---|---| +| `vacia.html` (arranque puro) | 16.026 ms | 15.883 ms | — (ES la línea base) | **−0,9 %** | +| DOM/maquetación | 23.307 ms | 20.627 ms | 7.281 → 4.744 ms | **−34,8 %** | +| carga ajena (canvas/JSON/img) | 20.576 ms | 20.517 ms | 4.550 → 4.634 ms | **+1,8 % (nada)** | +| SunSpider `3d-raytrace` | 15.992 ms | 15.877 ms | **−34 → −6 ms** | bajo el ruido | + +Las cuatro cargas y las dos variantes, **en una sola sesión intercalada**: restar el arranque de una +corrida al total de otra no vale, porque la misma variante deriva ~1 % entre días. + +**Qué cambia, en concreto:** + +1. **El «−10,9 %» que publiqué es correcto como número y engañoso como afirmación.** Es real para el + ciclo completo, que es lo que un usuario espera al abrir el navegador. Pero se leía como + «firefox es un 11 % más rápido», y sobre el trabajo de la página la mejora es **−34,8 %**: el + PGO rinde TRES VECES más de lo que dije. El error subestimaba mi propio resultado. + +2. **La explicación que di del SunSpider era aire.** Escribí que el −1,0 % se explicaba porque un + benchmark JIT-bound es ciego al PGO. Mirá la fila: su trabajo mide **−34 ms**, negativo — la + página con el benchmark tardó MENOS que la vacía. `3d-raytrace` corre en decenas de ms y su + trabajo es más chico que la variación entre corridas. **Ahí no había nada que medir.** El −1,0 % + era el −0,9 % del arranque, y yo le colgué encima una teoría sobre el JIT. + + La teoría puede ser cierta —el mecanismo es real y está bien descrito— pero **esta medición nunca + la probó**, y la presenté como si sí. Un número real más un mecanismo real no hacen una + explicación: hace falta que el número mida el mecanismo. + +3. **La carga ajena confirma que el PGO no es magia.** +1,8 % sobre su trabajo, o sea cero: mejora + lo que se le entrenó (maquetación, −34,8 %) y no lo que no (canvas/JSON, 0 %). Eso es exactamente + lo que un PGO honesto debe hacer, y es mejor evidencia de que funciona que el número grande. + +4. **El jarlog no se rehabilita.** Su −0,1 % diluido pasa a ~−0,5 % sin diluir; sigue muy por debajo + del ~1 % que la misma variante deriva entre días. La conclusión de aparcarlo no se mueve. + +⚠ **La lección, que es la misma de toda esta jornada con otro disfraz.** El instrumento funcionaba, +las medianas eran correctas, las corridas estaban intercaladas, los rangos no se solapaban — todo el +rigor estadístico estaba puesto **sobre una cantidad que no era la que yo creía estar midiendo**. +Ninguna cantidad de repeticiones lo habría revelado: sólo lo revela un control, y el control costó +siete corridas de una página vacía. **Antes de refinar la precisión de un número, hay que gastar una +medición en averiguar qué mide.** + +Y el detalle que lo vuelve barato de recordar: el control salió NEGATIVO en una fila. Un valor +imposible es la forma más limpia que tiene una medición de avisar que el modelo está mal, y por eso +esa fila se deja publicada con su signo menos en lugar de redondearla a cero. + **Y la pregunta que un insumo no determinista obliga a hacer, respondida: `firefox` SIGUE REPRODUCIENDO bit a bit** (`verificar-repro.sh`: REPRODUCEN 1, DERIVA 0, NO-DETERMINISMO 0). Era el riesgo real de esta unidad, no el rendimiento: si el `-fprofile-use` hubiera metido cualquier diff --git a/docs/evidencia/pgo-banco-final-2026-09-08.txt b/docs/evidencia/pgo-banco-final-2026-09-08.txt new file mode 100644 index 00000000..a6cc39f9 --- /dev/null +++ b/docs/evidencia/pgo-banco-final-2026-09-08.txt @@ -0,0 +1,22 @@ +== vacia.html + sin: 16101 16032 16010 16026 16074 15996 16019 + pgo: 15860 15961 15939 15921 15864 15870 15883 + medianas sin=16026 pgo=15883 (-0.9%) +== fuera-del-corpus.html + sin: 23078 23307 23314 23017 23140 23391 23370 + pgo: 20533 20746 20657 20627 20813 20501 20512 + medianas sin=23307 pgo=20627 (-11.5%) +== del-corpus.html + sin: 16073 15992 15964 15948 16008 15967 16030 + pgo: 15843 15866 15940 15877 15888 15849 15891 + medianas sin=15992 pgo=15877 (-0.7%) +== ajena.html + sin: 20642 20576 20554 20557 20556 20578 20598 + pgo: 20517 20517 20531 20545 20479 20490 20513 + medianas sin=20576 pgo=20517 (-0.3%) + +== TRABAJO REAL (total − arranque), que es lo comparable entre cargas + carga trabajo sin / con pgo mejora del trabajo + fuera-del-corpus.html 7281 / 4744 ms -34.8% + del-corpus.html -34 / -6 ms (trabajo ~0: bajo el ruido) + ajena.html 4550 / 4634 ms +1.8% diff --git a/scripts/diagnostico/ajena.html b/scripts/diagnostico/ajena.html new file mode 100644 index 00000000..695370e1 --- /dev/null +++ b/scripts/diagnostico/ajena.html @@ -0,0 +1,48 @@ +ajena +
+ diff --git a/scripts/diagnostico/banco-pgo-final.sh b/scripts/diagnostico/banco-pgo-final.sh new file mode 100755 index 00000000..2fc3782e --- /dev/null +++ b/scripts/diagnostico/banco-pgo-final.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Banco DEFINITIVO: las cuatro cargas y las dos variantes en UNA SOLA sesión intercalada, para que +# la resta «total − arranque» sea válida. Las restas entre corridas de días distintos no lo son: +# el arranque medido hoy no es necesariamente el de ayer. +# vacia → ARRANQUE PURO. Sin este control todos los porcentajes están diluidos por +# una constante que resultó ser ~16 s, o sea la mayor parte de la medición. +# fuera-del-corpus → DOM/layout: parentesco con lo que entrena el corpus +# del-corpus → SunSpider 3d-raytrace: JIT-bound +# ajena → imágenes, canvas, JSON, DOM por API: SIN parentesco +set -u +RAIZ=/mnt/vvv/hammer; R=$RAIZ/store/.rootfs/sway-v2 +AQUI=$(cd "$(dirname "$0")" && pwd) # las 4 páginas viven junto a este script +SAL=$(mktemp -d) +A=$(ls -d $RAIZ/store/8116bdec*-firefox|head -1); B=$(ls -d $RAIZ/store/3d199174*-firefox|head -1) +N=${N:-7} +corre(){ local ini fin + ini=$(date +%s%N) + timeout 300 bwrap --ro-bind "$R" / --ro-bind /usr/lib/musl/lib/libc.so /lib/ld-musl-x86_64.so.1 \ + --ro-bind "$1/usr/lib/firefox" /usr/lib/firefox --dev /dev --proc /proc --tmpfs /run --tmpfs /tmp \ + --unshare-pid --ro-bind "$AQUI" /bench --bind "$SAL" /salida --unshare-user --uid 0 --gid 0 \ + --setenv PATH /usr/bin:/bin \ + /bin/sh -c 'export HOME=/tmp/h MOZ_HEADLESS=1 MOZ_DISABLE_CONTENT_SANDBOX=1 LIBGL_ALWAYS_SOFTWARE=1 LANG=C.UTF-8; mkdir -p $HOME + LD_LIBRARY_PATH=/usr/lib/firefox /usr/lib/firefox/firefox --headless --screenshot /salida/b.png file:///bench/'"$2" \ + >/dev/null 2>&1 + fin=$(date +%s%N); echo $(( (fin-ini)/1000000 )); } +med(){ printf '%s\n' "$@"|sort -n|awk '{v[NR]=$1}END{print (NR%2)?v[(NR+1)/2]:int((v[NR/2]+v[NR/2+1])/2)}'; } +declare -A MA MB +for p in vacia.html fuera-del-corpus.html del-corpus.html ajena.html; do + corre "$A" "$p" >/dev/null; corre "$B" "$p" >/dev/null + sa=(); sb=() + for i in $(seq 1 $N); do sa+=( "$(corre "$A" "$p")" ); sb+=( "$(corre "$B" "$p")" ); done + MA[$p]=$(med "${sa[@]}"); MB[$p]=$(med "${sb[@]}") + echo "== $p"; echo " sin: ${sa[*]}"; echo " pgo: ${sb[*]}" + echo " medianas sin=${MA[$p]} pgo=${MB[$p]} ($(awk -v a=${MA[$p]} -v b=${MB[$p]} 'BEGIN{printf "%+.1f%%",(b-a)*100.0/a}'))" +done +echo "" +echo "== TRABAJO REAL (total − arranque), que es lo comparable entre cargas" +ba=${MA[vacia.html]}; bb=${MB[vacia.html]} +printf " %-22s %-22s %s\n" "carga" "trabajo sin / con pgo" "mejora del trabajo" +for p in fuera-del-corpus.html del-corpus.html ajena.html; do + awk -v p="$p" -v a=${MA[$p]} -v b=${MB[$p]} -v ba=$ba -v bb=$bb 'BEGIN{ + ta=a-ba; tb=b-bb; + if (ta<=50) printf " %-22s %-22s %s\n", p, ta" / "tb" ms", "(trabajo ~0: bajo el ruido)"; + else printf " %-22s %-22s %+.1f%%\n", p, ta" / "tb" ms", (tb-ta)*100.0/ta }' +done diff --git a/scripts/diagnostico/del-corpus.html b/scripts/diagnostico/del-corpus.html new file mode 100644 index 00000000..2097d423 --- /dev/null +++ b/scripts/diagnostico/del-corpus.html @@ -0,0 +1,490 @@ + + + + +SunSpider 3d-raytrace + + + +

3d-raytrace

+
+
+ + + + + + diff --git a/scripts/diagnostico/fuera-del-corpus.html b/scripts/diagnostico/fuera-del-corpus.html new file mode 100644 index 00000000..db561c11 --- /dev/null +++ b/scripts/diagnostico/fuera-del-corpus.html @@ -0,0 +1,20 @@ +bench + +
+ diff --git a/scripts/diagnostico/vacia.html b/scripts/diagnostico/vacia.html new file mode 100644 index 00000000..2417d03a --- /dev/null +++ b/scripts/diagnostico/vacia.html @@ -0,0 +1 @@ +vacia

nada

\ No newline at end of file