English · Español
Lab 03 — Dibuja el roofline para tu ordenador¶
Objetivo: producir el artefacto canónico de la Fase 1 — una gráfica de roofline para tu CPU, con tus kernels medidos colocados sobre ella. Este es el archivo que vas a referenciar desde cada fase posterior que discuta rendimiento.
Tiempo estimado: 90–120 minutos.
Prerrequisito: labs 00, 01, 02 todos comprometidos.
Qué produces¶
Un directorio experiments/01-roofline/ que contenga:
roofline.py— script que dibuja la gráfica.roofline.png— la gráfica en sí. Este es el artefacto que citaPHASE_01_REPORT.md.kernels.json— intensidad y rendimiento medido por kernel.manifest.json.README.mdinterpretando la gráfica.
La gráfica a producir¶
Ejes log-log:
- eje x: intensidad aritmética (FLOPs / byte), log10 desde 0.01 hasta 100.
- eje y: rendimiento (GFLOPS), log10 desde 0.1 hasta pico × 1.5.
Líneas a dibujar:
1. Techo de memoria. Diagonal: y = β_peak × x. Usa β medido del lab 01.
2. Techo de cómputo. Horizontal: y = π_peak. Usa un pico medido si tienes uno (ver Bloque C); en otro caso, el valor derivado del lab 00 anotándolo.
3. Techo de memoria opcional secundario para el ancho de banda L3 (de la meseta del lab 01), mostrado como una línea más tenue por encima de la línea de DRAM.
Puntos a colocar:
- memcpy a intensidad ~0.0 (no hace FLOPs; fuera del borde izquierdo — convención: coloca un punto en el x-tick más a la izquierda con y = tu throughput medido como referencia de cordura).
- producto escalar de vectores fp32 de longitud 10⁶.
- matmul ingenuo 1024×1024 fp32.
- matmul de NumPy 1024×1024 fp32.
Para cada punto, computa la intensidad (archivo de teoría §3) y mide el rendimiento, luego coloca.
TODOs¶
Bloque A — recoge las constantes del ordenador¶
-
β_peak: toma la asíntota de cola derecha deexperiments/01-memcpy-bandwidth/bandwidth.png(o la entrada relevante en suresults.json). -
π_peak: deexperiments/01-machine-profile/profile.md. Nota que esto es derivado, no medido. El Bloque C de abajo lo hace medido si quieres.
Bloque B — mide cuatro kernels¶
- memcpy — reutiliza el throughput del buffer más grande del lab 01. No se necesita nueva medición; cita
results.jsondirectamente. - dot(a, b) para fp32 de longitud 10⁶. FLOPs =
2N - 1 ≈ 2 × 10⁶. Bytes movidos (sin reutilización) =8N = 8 × 10⁶. Intensidad = 0.25 FLOPs/byte. Mide connp.dot(a, b), repite ≥ 100 veces, computa GFLOPS =2N / mean_seconds / 10⁹. - matmul ingenuo — implementa con tres bucles anidados de Python (sí, Python; deliberadamente lento). N = 128 (cualquier cosa mayor tarda horas). FLOPs =
2N³. Intensidad ≈ 0.25 (la misma de antes; el matmul ingenuo no reutiliza nada). Mide el tiempo. Computa GFLOPS. - np.matmul —
np.matmul(A, B)para N = 1024. FLOPs =2N³. Mide el tiempo. Computa GFLOPS. Para la intensidad, coloca este punto en la intensidad efectiva que alcanza — esta es aproximadamente la intensidad operacional del algoritmo por bloques de MKL, que puedes dejar como "mejor ajuste sobre el roofline" sin demostrarlo.
Bloque C — (opcional, recomendado) mide FLOPS pico¶
Sustituye el π_peak derivado por uno medido:
- Escribe un bucle ajustado que haga fused multiply-adds sobre entradas amigas de AVX2.
- La aproximación portable más limpia en NumPy puro es
c = a * a + asobre un array pequeño dimensionado para caber en L1, repetidoKveces. - Cronometra. Computa GFLOPS. Este es tu
πmedido. - Si está dentro del 30% del derivado, usa el derivado (número redondo); si está muy lejos, usa el medido y nota por qué.
Si las FLOPS medidas son mucho menores que las derivadas (50%+), probablemente el chip está limitado térmicamente — los Intel de la serie U lo hacen rutinariamente. Documéntalo en
README.md.
Bloque D — dibuja la gráfica¶
- matplotlib. Ambos ejes log.
- Techo de memoria: línea diagonal
y = β × xdesde(x_min, β × x_min)hasta(π/β, π)— es decir, hasta que golpea el techo de cómputo en la esquina. - Techo de cómputo: horizontal
y = πdesde la esquina hacia la derecha. - Puntos: scatter en
(I_kernel, perf_kernel)con etiquetas. - Anota:
I_crit = π / βen la esquina. - Guarda como
roofline.png(DPI alto; esto va al sitio de docs).
Bloque E — interpreta¶
En README.md:
- Enuncia el equilibrio del ordenador. "
I_crit = XFLOPs/byte. Cualquier kernel por debajo de esto está memory-bound en este ordenador." - Coloca cada kernel medido. "memcpy está en perf = β = ~Y GB/s. El matmul ingenuo está en 0.25 FLOPs/byte y solo ~Z GFLOPS — muy por debajo del techo de memoria, indicando overhead de Python, no memoria. np.matmul está cerca de la esquina en ~W GFLOPS."
- Haz la observación clave. El matmul ingenuo hace la misma matemática que np.matmul. La brecha 50–100× es enteramente jerarquía de memoria + SIMD, no algoritmo. Enuncia esto; es la conclusión principal de la Fase 1.
Restricciones¶
- La gráfica del roofline debe dibujarse desde tus propias mediciones (
βdel lab 01,πdel Bloque A o Bloque C de este lab, los puntos de los kernels desde tus propias ejecuciones). Sin números de fabricante, sin datasets online. - Guarda las mediciones de los kernels en
kernels.jsoncon la misma disciplina demanifest.json.
Condiciones de parada¶
Terminado cuando:
roofline.pngexiste.- Tiene los dos techos, la anotación de la esquina y los cuatro puntos de kernel.
README.mdhace el argumento "ingenuo vs np.matmul es memoria, no matemática" explícitamente.- Puedes mostrarte la gráfica a ti mismo, apuntar a cualquier punto, y explicar en una frase qué cuello de botella se aplica.
PHASE_01_REPORT.md(escrito por separado en el cierre de fase) referenciaroofline.png.
Escollos¶
- El matmul ingenuo en Python a N=1024 son horas. Usa N=128 y escala los FLOPs en consecuencia. La idea no es cronometrar un matmul ingenuo grande; es poner el punto en la zona correcta de la gráfica.
- La "intensidad" de np.matmul es difusa. Está bloqueado en múltiples niveles de cache; la intensidad efectiva depende de N. Para N = 1024, MKL alcanza ~70% del pico — coloca el punto en
(I = π / β × 0.7, perf = 0.7 π)como representación justa. Anota esta aproximación enREADME.md. - La gráfica se ve vacía. Los ejes log con pocos puntos siempre se ven dispersos. La forma (esquina, pendiente, techo) es el entregable, no la densidad de puntos.
Cuándo consultar solutions/¶
Después de comprometer los cinco archivos en este directorio. Solución en solutions/03-roofline-ref.md (escrita en apertura de fase).
El trabajo de lab de la Fase 1 está completo. Siguiente: /quiz 01, luego PHASE_01_REPORT.md, luego reflexión, luego proceed.