Problemas de aula resueltos
Teoría: Tema 1 - Evaluación de las prestaciones · Tema 2 - Diseño de algoritmos paralelos · Exámenes: Problemas de examen resueltos
Receta para cualquier problema de prestaciones
- secuencial: contar FLOPs × .
- : lo que tarda el procesador más cargado: su cálculo + sus comunicaciones. Cada mensaje cuesta ; un envío y una recepción cuentan como dos mensajes (en el curso se suman, no se solapan).
- Coste: .
- Sobrecarga: . El término de cálculo se cancela si el reparto es perfecto: lo que queda en es lo que "sobra" (comunicaciones, desequilibrio, cálculo redundante).
- Speedup y eficiencia: , . Truco: dividir numerador y denominador para dejar .
- Escalabilidad (isoeficiencia): , término a término (, , ). Para cada uno despejar en función de :
- Si sale : óptima. : buena. o peor: pobre.
- Si aparece igual en los dos lados y se cancela (): no escala.
- Si el término no depende de : no afecta.
- Ojo con las restricciones entre y (p. ej. o ): aunque sea 0, si no puede pasar de , el problema tiene que crecer como para usar más procesadores.
Evaluación de las prestaciones
Todos los problemas usan el mismo dominio: una matriz , 1 FLOP por elemento, y cada elemento depende solo de sus vecinos de arriba y de abajo (la figura del enunciado es una malla con aristas solo verticales). Por tanto:
Problema 1: una tarea por elemento ()
Cada procesador actualiza un elemento (1 FLOP) e intercambia su valor con el vecino de arriba y el de abajo: 2 envíos + 2 recepciones = 4 mensajes de 1 dato.
Interpretación:
- no tiene término en : el cálculo está perfectamente repartido.
- La eficiencia no depende ni de ni de : es constante, así que el algoritmo es escalable sin hacer más cálculos (en isoeficiencia: , no depende de ). El tiempo paralelo también es constante.
- Pero la eficiencia es malísima: con , , sale y s. Cada tarea hace 1 FLOP y 4 mensajes: la granularidad es demasiado fina. Hay que agrupar.
Escalable no significa eficiente
Una eficiencia constante pero de 0.002 es escalable y, aun así, un diseño inútil.
Problema 2: agrupar por filas y por columnas ()
Por filas. Cada procesador tiene una fila completa ( elementos). Las dependencias son verticales, así que necesita la fila de arriba y la de abajo: 4 mensajes de datos.
La eficiencia sube con pero se estanca en (con los valores de antes, ). En términos de Kumar escala pobremente: .
Por columnas. Cada procesador tiene una columna completa. Como las dependencias son verticales, todas quedan dentro de la columna: no hay comunicaciones.
Es el diseño ideal en cuanto a eficiencia, pero como y , para usar más procesadores el problema tiene que crecer como .
La lección del problema 2
Agrupa en la dirección de las dependencias. Si las dependencias van en vertical, las columnas las contienen enteras y la relación superficie/volumen es 0. Por filas cortas justo las dependencias.
En la gráfica de eficiencia escalada de clase (diapositiva 7), con las dos curvas caen, y la de filas queda por encima de la de columnas. Con atado, ninguna de las dos mantiene el tiempo al multiplicar y por el mismo factor. El arreglo es el problema 4: desatar de .
Problema 3: columnas + carga/descarga de datos ()
Ahora se cuenta repartir la matriz y recogerla. Un procesador envía a los otros su columna ( datos) uno a uno (P2P no optimizado), y al final se recoge igual: mensajes de datos.
Isoeficiencia (con ):
- : → escalable pero no óptimo (cuadrática).
- : → escalabilidad muy pobre.
Lección: la distribución secuencial desde un nodo arruina un diseño que sin ella era perfecto. En la comparativa de clase, "columnas + E/S" es con diferencia la peor curva.
Problema 4: columnas con
Cada procesador tiene columnas (bloques de columnas consecutivas). Sigue sin haber comunicaciones:
Es la generalización del caso por columnas. Ahora ya no está atado a : mientras , es perfecto.
Problema 5: filas con
Cada procesador tiene filas consecutivas. Solo las filas de los bordes del bloque tienen que comunicarse (con el bloque de arriba y el de abajo): siguen siendo 4 mensajes de datos, pero ahora con mucho más cálculo por procesador.
- : → escalable óptimo.
- : → no óptimo, isoeficiencia cuadrática.
La eficiencia escalada baja despacio (≈ 0.55 con ): mucho mejor que con .
Problema 6: el problema 4 + carga/descarga
Repartir los bloques de datos desde un nodo y recogerlos, P2P no optimizado:
- : .
- : → se cancela: no es escalable. Por mucho que crezca la matriz, el reparto cuesta tanto como el propio problema.
(En la diapositiva hay una errata en el paso intermedio de , que pone donde debería poner ; el resultado final es el correcto.)
Problema 7: el problema 5 + carga/descarga
- : .
- : → no escala (el término de no depende de ).
Comparativa final (eficiencia escalada)
| Diseño | Comportamiento |
|---|---|
| Bloques de columnas, | : perfecto |
| Bloques de filas, | Baja muy despacio |
| Filas, | Baja más rápido |
| Columnas, | Baja todavía más |
| Cualquiera + E/S | Se desploma: no escala |
Diseño de algoritmos paralelos
Problema 1: procesado de imágenes en 5 fases
Enunciado: imágenes; cada una pasa, en orden, por lectura, corrección de brillo, detección de bordes, compresión y almacenamiento. procesadores. Aplicar las dos primeras etapas de Foster y decir qué patrón describe la solución.
1. Descomposición: funcional. El trabajo sobre cada imagen se divide en fases que hacen operaciones distintas. Se definen 5 tipos de tareas: (lectura), (brillo), (bordes), (compresión) y (almacenamiento). Para cada imagen :
2. Comunicaciones: locales, estáticas y regulares: cada fase envía la imagen procesada solo a la siguiente. No hay dependencias entre imágenes distintas.
Patrón: pipeline (segmentación). Mientras trata la imagen 1, ya lee la imagen 2, etc. Una vez lleno el cauce, sale una imagen por "ciclo".
¿Y si es pequeño o las fases tienen costes muy distintos?
- pequeño: el tiempo de llenado y vaciado del pipeline pesa mucho; con pocas imágenes casi nunca están las 5 fases trabajando a la vez.
- Costes desiguales: la fase más lenta marca el ritmo y las demás esperan (falta de equidad en la granularidad).
- Alternativas: descomposición del dominio sobre las imágenes (granja de procesos / trabajadores replicados: cada procesador hace las 5 fases de imágenes distintas, con reparto dinámico si los costes varían); replicar la fase lenta; agrupar fases baratas en un mismo procesador para equilibrar.
Problema 2: índice invertido sobre documentos
Enunciado: construir, para cada palabra, la lista de documentos donde aparece (p. ej. ). Dos primeras etapas y patrón.
1. Descomposición del dominio sobre los datos de entrada: se reparten los documentos entre las tareas.
2. Comunicaciones en tres fases:
- Map: cada tarea procesa sus documentos de forma independiente y genera pares . Sin comunicación.
- Shuffle (redistribución): se reúnen todos los pares con la misma clave (palabra) en la misma tarea. Es una comunicación global, todos con todos (cada tarea puede tener pares para cualquier otra).
- Reduce: cada tarea combina las listas de sus palabras y obtiene la parte del índice global (nuevo reparto de trabajo: ahora por palabras).
Patrón: MapReduce.
¿Problemas?
- Desequilibrio: documentos de tamaños muy distintos y palabras con frecuencias muy desiguales (unas pocas palabras aparecen en casi todos los documentos), así que algunas tareas de reduce reciben muchísimo más trabajo.
- Coste del shuffle: comunicación todos con todos, la más cara.
- Mitigaciones: asignación dinámica (bolsa de tareas), repartir las claves con una función hash, combinar localmente antes del shuffle (enviar una lista por palabra y no un par por aparición: menos mensajes y más grandes).
Problema 3
Es el problema 22 del boletín de exámenes (normalización por filas). Está resuelto en Problemas de examen resueltos.