En informática , el operador de reducción [ 1 ] es un tipo de operador que se usa comúnmente en programación paralela para reducir los elementos de un arreglo a un solo resultado. Los operadores de reducción son asociativos y a menudo (pero no necesariamente) conmutativos . [ 2 ] [ 3 ] [ 4 ] La reducción de conjuntos de elementos es una parte integral de modelos de programación como MapReduce , donde se aplica ( mapea ) un operador de reducción a todos los elementos antes de reducirlos. Otros algoritmos paralelos usan operadores de reducción como operaciones primarias para resolver problemas más complejos. Muchos operadores de reducción se pueden usar para difusión para distribuir datos a todos los procesadores.
Teoría
Un operador de reducción permite dividir una tarea en varias subtareas calculando resultados parciales que se utilizan para obtener un resultado final. Permite ejecutar ciertas operaciones en serie en paralelo y reducir el número de pasos necesarios para dichas operaciones. El operador de reducción almacena el resultado de las subtareas en una copia privada de la variable. Estas copias privadas se combinan posteriormente en una copia compartida.
Un operador es un operador de reducción si:
- Puede reducir una matriz a un único valor escalar. [ 2 ]
- El resultado final debería poder obtenerse a partir de los resultados de las tareas parciales que se crearon. [ 2 ]
Estos dos requisitos se cumplen para los operadores conmutativos y asociativos que se aplican a todos los elementos de la matriz.
Algunos operadores que cumplen estos requisitos son la suma, la multiplicación y algunos operadores lógicos (y, o, etc.).
Un operador de reducción se puede aplicar en tiempo constante a un conjunto de vectores de entrada con elementos cada uno. El resultado de la operación es la combinación de los elementos y debe almacenarse en un procesador raíz específico al final de la ejecución. Si el resultado debe estar disponible en todos los procesadores una vez finalizado el cálculo, a menudo se denomina Allreduce. Un algoritmo secuencial óptimo de tiempo lineal para la reducción puede aplicar el operador sucesivamente de adelante hacia atrás, reemplazando siempre dos vectores con el resultado de la operación aplicada a todos sus elementos, creando así una instancia con un vector menos. Necesita pasos hasta que solo queda. Los algoritmos secuenciales no pueden ser mejores que el tiempo lineal, pero los algoritmos paralelos dejan cierto margen para la optimización.
Ejemplo
Supongamos que tenemos un array . La suma de este array se puede calcular en serie reduciendo secuencialmente el array a una sola suma usando el operador '+'. Comenzando la suma desde el principio del array se obtiene: Como '+' es conmutativo y asociativo, es un operador de reducción. Por lo tanto, esta reducción se puede realizar en paralelo usando varios núcleos, donde cada núcleo calcula la suma de un subconjunto del array, y el operador de reducción combina los resultados. Usando una reducción de árbol binario permitiría que 4 núcleos calculen , , , y . Luego, dos núcleos pueden calcular y , y finalmente un solo núcleo calcula . Así que se pueden usar un total de 4 núcleos para calcular la suma en pasos en lugar de los pasos requeridos para la versión en serie. Esta técnica de árbol binario paralelo calcula . Por supuesto, el resultado es el mismo, pero solo debido a la asociatividad del operador de reducción. La conmutatividad del operador de reducción sería importante si existiera un núcleo maestro que distribuyera el trabajo a varios procesadores, ya que en ese caso los resultados podrían regresar al procesador maestro en cualquier orden. La propiedad de conmutatividad garantiza que el resultado será el mismo.
IEEE 754-2019 define 4 tipos de reducciones de suma y 3 tipos de reducciones de producto escalado. Dado que las operaciones son operadores de reducción, la norma especifica que "las implementaciones pueden asociarse en cualquier orden o evaluarse en cualquier formato más amplio". [ 5 ]
Ninguno de los ejemplos
La multiplicación de matrices no es un operador de reducción, ya que no es conmutativa. Si se permitiera a los procesos devolver los resultados de la multiplicación de matrices al proceso maestro en cualquier orden, el resultado final que este calculara probablemente sería incorrecto si los resultados llegaran desordenados. Sin embargo, cabe destacar que la multiplicación de matrices es asociativa y, por lo tanto, el resultado sería correcto siempre que se respetara el orden adecuado, como en la técnica de reducción mediante árboles binarios.
Algoritmos
Algoritmos de árbol binomial
En cuanto a los algoritmos paralelos, existen dos modelos principales de computación paralela: la máquina de acceso aleatorio paralelo (PRAM), una extensión de la RAM con memoria compartida entre unidades de procesamiento, y la computadora paralela síncrona masiva , que considera la comunicación y la sincronización . Ambos modelos tienen implicaciones diferentes en la complejidad temporal ; por lo tanto, se mostrarán dos algoritmos.
algoritmo PRAM
Este algoritmo representa un método ampliamente utilizado para manejar entradas donde es una potencia de dos. El procedimiento inverso se usa frecuentemente para la difusión de elementos. [ 6 ] [ 7 ] [ 8 ]

- para hacer
- para hacerlo en paralelo
- si está activo entonces
- si el bit de está activado entonces
- establecido como inactivo
- de lo contrario si
- si el bit de está activado entonces
- si está activo entonces
- para hacerlo en paralelo
El operador binario para vectores se define elemento a elemento de tal manera que
El algoritmo asume además que al principio para todos y es una potencia de dos y utiliza las unidades de procesamiento . En cada iteración, la mitad de las unidades de procesamiento se vuelven inactivas y no contribuyen a los cálculos posteriores. La figura muestra una visualización del algoritmo utilizando la suma como operador. Las líneas verticales representan las unidades de procesamiento donde se realiza el cálculo de los elementos en esa línea. Los ocho elementos de entrada se encuentran en la parte inferior y cada paso de animación corresponde a un paso paralelo en la ejecución del algoritmo. Un procesador activo evalúa el operador dado en el elemento que actualmente contiene y donde es el índice mínimo que cumple , de modo que se convierte en un procesador inactivo en el paso actual. y no son necesariamente elementos del conjunto de entrada, ya que los campos se sobrescriben y se reutilizan para expresiones evaluadas previamente. Para coordinar los roles de las unidades de procesamiento en cada paso sin causar comunicación adicional entre ellas, se utiliza el hecho de que las unidades de procesamiento están indexadas con números del al . Cada procesador examina su -ésimo bit menos significativo y decide si se vuelve inactivo o calcula el operador en su propio elemento y el elemento con el índice donde el -ésimo bit no está activado. El patrón de comunicación subyacente del algoritmo es un árbol binomial, de ahí el nombre del algoritmo.
Solo contiene el resultado al final, por lo tanto, es el procesador raíz. Para una operación Allreduce , el resultado debe distribuirse, lo que se puede hacer agregando una difusión desde . Además, el número de procesadores está restringido a ser una potencia de dos. Esto se puede eliminar rellenando el número de procesadores hasta la siguiente potencia de dos. También hay algoritmos más adecuados para este caso de uso. [ 9 ]
Análisis del tiempo de ejecución
El bucle principal se ejecuta veces, el tiempo necesario para la parte realizada en paralelo es en ya que una unidad de procesamiento combina dos vectores o se vuelve inactiva. Por lo tanto, el tiempo paralelo para la PRAM es . La estrategia para manejar conflictos de lectura y escritura puede elegirse tan restrictiva como lectura exclusiva y escritura exclusiva (EREW). La aceleración del algoritmo es y por lo tanto la eficiencia es . La eficiencia se ve afectada porque la mitad de las unidades de procesamiento activas se vuelven inactivas después de cada paso, por lo que las unidades están activas en el paso .
Algoritmo de memoria distribuida
A diferencia del algoritmo PRAM, en el modelo de memoria distribuida , la memoria no se comparte entre las unidades de procesamiento y los datos deben intercambiarse explícitamente entre ellas. Por lo tanto, los datos deben intercambiarse explícitamente entre las unidades, como se puede observar en el siguiente algoritmo.
- para hacer
- para hacerlo en paralelo
- si está activo entonces
- si el bit de está activado entonces
- enviar a
- establecido como inactivo
- de lo contrario si
- recibir
- si el bit de está activado entonces
- si está activo entonces
- para hacerlo en paralelo
La única diferencia entre el algoritmo distribuido y la versión PRAM es la inclusión de primitivas de comunicación explícitas; el principio de funcionamiento sigue siendo el mismo.
Análisis del tiempo de ejecución
La comunicación entre unidades genera cierta sobrecarga. Un análisis simple del algoritmo utiliza el modelo BSP e incorpora el tiempo necesario para iniciar la comunicación y el tiempo necesario para enviar un byte. El tiempo de ejecución resultante es , ya que los elementos de un vector se envían en cada iteración y tienen un tamaño total.
Algoritmo de canalización

Para los modelos de memoria distribuida, puede tener sentido usar comunicación en pipeline. Esto es especialmente cierto cuando es pequeño en comparación con . Por lo general, los pipelines lineales dividen los datos o las tareas en partes más pequeñas y las procesan en etapas. A diferencia de los algoritmos de árbol binomial, el algoritmo en pipeline utiliza el hecho de que los vectores no son inseparables, pero el operador puede evaluarse para elementos individuales: [ 10 ]
- para hacer
- para hacerlo en paralelo
- si
- enviar a
- si
- recibir de
- si
- para hacerlo en paralelo
Es importante destacar que las operaciones de envío y recepción deben ejecutarse simultáneamente para que el algoritmo funcione. El vector resultante se almacena al final. La animación muestra la ejecución del algoritmo en vectores de tamaño cuatro con cinco unidades de procesamiento. Dos pasos de la animación visualizan un paso de ejecución paralela.
Análisis del tiempo de ejecución
El número de pasos en la ejecución paralela es , se requieren pasos hasta que la última unidad de procesamiento recibe su primer elemento y pasos adicionales hasta que se reciben todos los elementos. Por lo tanto, el tiempo de ejecución en el modelo BSP es , suponiendo que es el tamaño total en bytes de un vector.
Aunque tiene un valor fijo, es posible agrupar lógicamente los elementos de un vector y reducirlo . Por ejemplo, una instancia de problema con vectores de tamaño cuatro se puede manejar dividiendo los vectores en los dos primeros y los dos últimos elementos, que siempre se transmiten y calculan juntos. En este caso, se envía el doble de volumen en cada paso, pero el número de pasos se ha reducido aproximadamente a la mitad. Esto significa que el parámetro se reduce a la mitad, mientras que el tamaño total en bytes permanece igual. El tiempo de ejecución para este enfoque depende del valor de , que se puede optimizar si y son conocidos. Es óptimo para , suponiendo que esto resulta en un menor que divide al original.
Aplicaciones
La reducción es una de las principales operaciones colectivas implementadas en la Interfaz de Paso de Mensajes , donde el rendimiento del algoritmo utilizado es importante y se evalúa constantemente para diferentes casos de uso. [ 11 ] Los operadores pueden usarse como parámetros para MPI_Reducey MPI_Allreduce, con la diferencia de que el resultado está disponible en una (raíz) unidad de procesamiento o en todas ellas.
OpenMP ofrece una cláusula de reducción para describir cómo se recopilan los resultados de las operaciones paralelas. [ 12 ]
MapReduce depende en gran medida de algoritmos de reducción eficientes para procesar grandes conjuntos de datos, incluso en clústeres enormes. [ 13 ] [ 14 ]
Algunos algoritmos de ordenación paralela utilizan reducciones para poder manejar conjuntos de datos muy grandes. [ 15 ]
Véase también
Referencias
- ↑ "Cláusula de reducción" . www.dartmouth.edu . Dartmouth College. 23 de marzo de 2009. Consultado el 26 de septiembre de 2016 .
- 1 2 3 Solihin, Yan (2016). Fundamentos de la arquitectura multinúcleo paralela . CRC Press. pág. 75. ISBN 978-1-4822-1118-4.
- ↑ Chandra, Rohit (2001). Programación paralela en OpenMP . Morgan Kaufmann. págs. 59–77 . ISBN 1558606718.
- ↑ Cole, Murray (2004). "Sacando esqueletos del armario: un manifiesto pragmático para la programación paralela esquelética" (PDF) . Computación paralela . 30 (3): 393. doi : 10.1016/j.parco.2003.12.002 . hdl : 20.500.11820/8eb79d42-de83-4cfb-9faa-30d9ac3b3839 .
- ↑ IEEE Computer Society (22 de julio de 2019). "9.4 Operaciones de reducción". Norma IEEE para aritmética de punto flotante . IEEE STD 754-2019. IEEE. págs. 1–84 . doi : 10.1109/IEEESTD.2019.8766229 . ISBN 978-1-5044-5924-2Norma IEEE 754-2019.
- ↑ Bar-Noy, Amotz; Kipnis, Shlomo (1994). "Difusión de múltiples mensajes en sistemas simultáneos de envío/recepción". Matemáticas Aplicadas Discretas . 55 (2): 95– 105. doi : 10.1016/0166-218x(94)90001-9 .
- ↑ Santos, Eunice E. (2002). "Algoritmos óptimos y eficientes para la suma y la suma de prefijos en máquinas paralelas". Journal of Parallel and Distributed Computing . 62 (4): 517– 543. doi : 10.1006/jpdc.2000.1698 .
- ↑ Slater, P.; Cockayne, E.; Hedetniemi, S. (1981-11-01). "Diseminación de información en árboles". SIAM Journal on Computing . 10 (4): 692– 701. doi : 10.1137/0210052 . ISSN 0097-5397 .
- ↑ Rabenseifner, Rolf; Träff, Jesper Larsson (19 de septiembre de 2004). «Algoritmos de reducción más eficientes para un número de procesadores que no es potencia de dos en sistemas paralelos de paso de mensajes». Avances recientes en máquinas virtuales paralelas e interfaces de paso de mensajes . Lecture Notes in Computer Science. Vol. 3241. Springer, Berlín, Heidelberg. pp. 36–46 . doi : 10.1007/978-3-540-30218-6_13 . ISBN 9783540231639.
- ↑ Bar-Noy, A.; Kipnis, S. (1994-09-01). "Diseño de algoritmos de difusión en el modelo postal para sistemas de paso de mensajes". Mathematical Systems Theory . 27 (5): 431– 452. CiteSeerX 10.1.1.54.2543 . doi : 10.1007/BF01184933 . ISSN 0025-5661 . S2CID 42798826 .
- ↑ Pješivac-Grbović, Jelena; Angskun, Thara; Bosilca, George; Fagg, Graham E.; Gabriel, Edgar; Dongarra, Jack J. (2007-06-01). "Análisis de rendimiento de operaciones colectivas MPI". Cluster Computing . 10 (2): 127– 143. CiteSeerX 10.1.1.80.3867 . doi : 10.1007/s10586-007-0012-0 . ISSN 1386-7857 . S2CID 2142998 .
- ↑ "10.9. Reducción: ejemplos de la interfaz de programación de aplicaciones OpenMP" . passlab.github.io .
- ↑ Lämmel, Ralf (2008). "El modelo de programación MapReduce de Google: una revisión". Science of Computer Programming . 70 (1): 1– 30. doi : 10.1016/j.scico.2007.07.001 .
- ↑ Senger, Hermes; Gil-Costa, Veronica; Arantes, Luciana; Marcondes, Cesar AC; Marín, Mauricio; Sato, Liria M.; da Silva, Fabrício AB (2016-06-10). "Análisis de costos y escalabilidad de BSP para operaciones MapReduce". Concurrency and Computation: Practice and Experience . 28 (8): 2503– 2527. doi : 10.1002/cpe.3628 . hdl : 10533/147670 . ISSN 1532-0634 . S2CID 33645927 .
- ↑ Axtmann, Michael; Bingmann, Timo; Sanders, Peter; Schulz, Christian (24-10-2014). "Clasificación masivamente paralela práctica". arXiv : 1410.6754 [ cs.DS ].
- Computación paralela