Articulo de referencia

Suma de prefijo

En informática , la suma de prefijos , suma acumulativa , escaneo inclusivo o simplemente escaneo de una secuencia de números 0 , ''x'' 1 , ''x'' 2 , ..."}},"i":0}}]}"> x 0 , x ...

En informática , la suma de prefijos , suma acumulativa , escaneo inclusivo o simplemente escaneo de una secuencia de números x 0 , x 1 , x 2 , ... es una segunda secuencia de números y 0 , y 1 , y 2 , ... , las sumas de prefijos ( totales acumulados ) de la secuencia de entrada:

y 0 = x 0
y 1 = x 0 + x 1
y 2 = x 0 + x 1 + x 2
...

Por ejemplo, las sumas de prefijos de los números naturales son los números triangulares :

Las sumas de prefijos son triviales de calcular en modelos de computación secuenciales, utilizando la fórmula y i = y i 1 + x i para calcular cada valor de salida en orden secuencial. Sin embargo, a pesar de su facilidad de cálculo, las sumas de prefijos son una primitiva útil en ciertos algoritmos como el ordenamiento por conteo , [ 1 ] [ 2 ] y forman la base de la función de orden superior de escaneo en lenguajes de programación funcional . Las sumas de prefijos también se han estudiado mucho en algoritmos paralelos , tanto como un problema de prueba a resolver como una primitiva útil para ser utilizada como subrutina en otros algoritmos paralelos. [ 3 ] [ 4 ] [ 5 ]

En abstracto, una suma de prefijos solo requiere un operador asociativo binario ⊕ , lo que la hace útil para muchas aplicaciones, desde el cálculo de descomposiciones de pares bien separadas de puntos hasta el procesamiento de cadenas. [ 6 ] [ 7 ]

Matemáticamente, la operación de sumas prefijas puede generalizarse de secuencias finitas a infinitas; en ese contexto, una suma prefija se conoce como suma parcial de una serie . La suma prefija o suma parcial constituye operadores lineales en los espacios vectoriales de secuencias finitas o infinitas; sus inversos son operadores de diferencias finitas .

Escanear función de orden superior

En términos de programación funcional , la suma de prefijos se puede generalizar a cualquier operación binaria (no solo a la suma ); la función de orden superior resultante de esta generalización se llama escaneo y está estrechamente relacionada con la operación de plegado . Tanto el escaneo como el plegado aplican la operación binaria dada a la misma secuencia de valores, pero se diferencian en que el escaneo devuelve toda la secuencia de resultados de la operación binaria, mientras que el plegado devuelve solo el resultado final. Por ejemplo, la secuencia de números factoriales se puede generar mediante un escaneo de los números naturales utilizando la multiplicación en lugar de la suma:

Escaneos inclusivos y exclusivos

Las implementaciones de escaneo en lenguajes de programación y bibliotecas pueden ser inclusivas o exclusivas . Un escaneo inclusivo incluye la entrada x i al calcular la salida y i (es decir,yi=j=0iincógnitaj{\textstyle y_ {i} = \ bigoplus _ {j = 0} ^ {i} x_ {j}}) mientras que un escaneo exclusivo no lo hace (es decir,yi=j=0i1incógnitaj{\textstyle y_ {i} = \ bigoplus _ {j = 0} ^ {i-1} x_ {j}}En este último caso, las implementaciones dejan y 0 sin definir o aceptan un valor " x −1 " separado para inicializar el escaneo. Cualquiera de los dos tipos de escaneo puede transformarse en el otro: un escaneo inclusivo puede transformarse en un escaneo exclusivo desplazando el arreglo producido por el escaneo un elemento a la derecha e insertando el valor de identidad a la izquierda del arreglo. A la inversa, un escaneo exclusivo puede transformarse en un escaneo inclusivo desplazando el arreglo producido por el escaneo a la izquierda e insertando la suma del último elemento del escaneo y el último elemento del arreglo de entrada a la derecha del arreglo. [ 8 ]

La siguiente tabla enumera ejemplos de las funciones de escaneo inclusivo y exclusivo que proporcionan algunos lenguajes de programación y bibliotecas:

El modelo de programación paralela OpenMP basado en directivas admite tanto el escaneo inclusivo como el exclusivo a partir de la versión 5.0.

Algoritmos paralelos

Existen dos algoritmos clave para calcular una suma de prefijos en paralelo. El primero ofrece un intervalo más corto y mayor paralelismo , pero no es eficiente en términos de recursos computacionales. El segundo es eficiente en términos de recursos computacionales, pero requiere el doble de tiempo y ofrece menor paralelismo. Estos se presentan a continuación.

Algoritmo 1: Menor intervalo, mayor paralelismo

Representación de circuito de una suma de prefijo paralelo de 16 entradas altamente paralela

Hillis y Steele presentan el siguiente algoritmo de suma de prefijos paralelo: [ 9 ]

para i <- 0 hasta log 2 ( n ) hacer para j <- 0 hasta n - 1 hacer en paralelo si j < 2 i entonces x i +1 j <- x i j sino x i +1 j <- x i j + x i j - 2 i

En lo anterior, la notaciónincógnitaji{\displaystyle x_{j}^{i}}significa el valor del j -ésimo elemento del array x en el paso de tiempo i .

Con un solo procesador, este algoritmo se ejecutaría en un tiempo de O ( n log n ) . [ 10 ] Sin embargo, si la máquina tiene al menos n procesadores para ejecutar el bucle interno en paralelo, el algoritmo en su conjunto se ejecuta en un tiempo de O (log n ) , el número de iteraciones del bucle externo.

Algoritmo 2: Eficiente en el trabajo

Representación en circuito de una suma de prefijo paralela de 16 entradas con alta eficiencia de trabajo.

Una suma de prefijos paralela eficiente en términos de trabajo se puede calcular siguiendo los siguientes pasos. [ 3 ] [ 11 ] [ 12 ]

  1. Calcula las sumas de pares consecutivos de elementos en los que el primer elemento del par tiene un índice par: z 0 = x 0 + x 1 , z 1 = x 2 + x 3 , etc.
  2. Calcula recursivamente la suma de prefijos w 0 , w 1 , w 2 , ... de la secuencia z 0 , z 1 , z 2 , ...
  3. Expresa cada término de la secuencia final y 0 , y 1 , y 2 , ... como la suma de hasta dos términos de estas secuencias intermedias: y 0 = x 0 , y 1 = z 0 , y 2 = z 0 + x 2 , y 3 = w 1 , etc. Después del primer valor, cada número sucesivo y i se copia desde una posición que está a la mitad de la distancia en la secuencia w , o es el valor anterior sumado a un valor en la secuencia x .

Si la secuencia de entrada tiene n pasos, la recursión continúa hasta una profundidad de O (log n ) , que también es el límite del tiempo de ejecución paralela de este algoritmo. El número de pasos del algoritmo es O ( n ) , y puede implementarse en una máquina de acceso aleatorio paralela con O ( n /log n ) procesadores sin ralentización asintótica alguna, asignando múltiples índices a cada procesador en las rondas del algoritmo en las que hay más elementos que procesadores. [ 3 ]

Discusión

Cada uno de los algoritmos anteriores se ejecuta en tiempo O (log n ) . Sin embargo, el primero requiere exactamente log₂n pasos , mientras que el segundo requiere 2 log₂n 2 pasos  . Para los ejemplos de 16 entradas ilustrados, el Algoritmo 1  es paralelo de 12 vías (49 unidades de trabajo divididas por un intervalo de 4), mientras que el Algoritmo 2  es paralelo de solo 4 vías (26 unidades de trabajo divididas por un intervalo de 6). Sin embargo, el Algoritmo  2 es eficiente en términos de trabajo : realiza solo un factor constante  (2) de la cantidad de trabajo requerida por el algoritmo secuencial ; mientras que el Algoritmo  1 es ineficiente en términos de trabajo : realiza asintóticamente más trabajo (un factor logarítmico) del que se requiere secuencialmente. En consecuencia,  es probable que el Algoritmo 1 tenga un mejor rendimiento cuando se dispone de un paralelismo abundante, pero es probable que el Algoritmo  2 tenga un mejor rendimiento cuando el paralelismo es más limitado.

Parallel algorithms for prefix sums can often be generalized to other scan operations on associative binary operations,[3][4] and they can also be computed efficiently on modern parallel hardware such as a GPU.[13] The idea of building in hardware a functional unit dedicated to computing multi-parameter prefix-sum was patented by Uzi Vishkin.[14]

Many parallel implementations follow a two pass procedure where partial prefix sums are calculated in the first pass on each processing unit; the prefix sum of these partial sums is then calculated and broadcast back to the processing units for a second pass using the now known prefix as the initial value. Asymptotically this method takes approximately two read operations and one write operation per item.

Concrete implementations of prefix sum algorithms

An implementation of a parallel prefix sum algorithm, like other parallel algorithms, has to take the parallelization architecture of the platform into account. More specifically, multiple algorithms exist which are adapted for platforms working on shared memory as well as algorithms which are well suited for platforms using distributed memory, relying on message passing as the only form of interprocess communication.

Shared memory: Two-level algorithm

The following algorithm assumes a shared memory machine model; all processing elements (PEs) have access to the same memory. A version of this algorithm is implemented in the Multi-Core Standard Template Library (MCSTL),[15][16] a parallel implementation of the C++ standard template library which provides adapted versions for parallel computing of various algorithms.

In order to concurrently calculate the prefix sum over n data elements with p processing elements, the data is divided into p+1{\displaystyle p+1} blocks, each containing np+1{\displaystyle {\frac {n}{p+1}}} elements (for simplicity we assume that p+1{\displaystyle p+1} divides n). Note, that although the algorithm divides the data into p+1{\displaystyle p+1} blocks, only p processing elements run in parallel at a time.

In a first sweep, each PE calculates a local prefix sum for its block. The last block does not need to be calculated, since these prefix sums are only calculated as offsets to the prefix sums of succeeding blocks and the last block is by definition not succeeded.

Los desplazamientos p que se almacenan en la última posición de cada bloque se acumulan en una suma de prefijo propia y se almacenan en sus posiciones subsiguientes. Si p es un número pequeño, es más rápido hacerlo de forma secuencial; si p es grande , este paso también se puede realizar en paralelo.

Se realiza un segundo barrido. En esta ocasión, no es necesario procesar el primer bloque, ya que no requiere tener en cuenta el desplazamiento del bloque anterior. Sin embargo, en este barrido se incluye el último bloque y se calculan las sumas de prefijo para cada bloque, considerando los desplazamientos de los bloques de suma de prefijo calculados en el barrido anterior.

función prefix_sum ( elementos ) { n := tamaño ( elementos ) p := número de elementos a procesar prefix_sum := [ 0. . .0 ] de tamaño n hacer paralelo i = 0 a p - 1 { // i := índice del PE actual desde j = i * n / ( p + 1 ) hasta ( i + 1 ) * n / ( p + 1 ) - 1 hacer { // Esto solo almacena la suma del prefijo de los bloques locales almacenar_prefijo_sum_con_desplazamiento_en ( elementos , 0 , prefijo_sum ) } } x = 0 para i = 1 a p { // Acumulación serial de la suma total de bloques x += prefijo_sum [ i * n / ( p + 1 ) - 1 ] // Construir la suma del prefijo sobre los primeros p bloques prefijo_sum [ i * n / ( p + 1 )] = x // Guardar los resultados para usarlos como desplazamientos en el segundo barrido } hacer paralelo i = 1 a p { // i := índice del PE actual desde j = i * n / ( p + 1 ) hasta ( i + 1 ) * n / ( p + 1 ) - 1 hacer { desplazamiento := suma_prefijo [ i * n / ( p + 1 )] // Calcular la suma del prefijo tomando la suma de los bloques precedentes como desplazamientoalmacenar_suma_prefijo_con_desplazamiento_en ( elementos , desplazamiento , suma_prefijo ) } } devolver suma_prefijo }

Mejora: En caso de que el número de bloques sea excesivo y el paso secuencial resulte lento al utilizar un solo procesador, se puede emplear el algoritmo de Hillis y Steele para acelerar la segunda fase.

Memoria distribuida: algoritmo de hipercubo

El algoritmo de suma de prefijos de hipercubo [ 17 ] está bien adaptado para plataformas de memoria distribuida y funciona con el intercambio de mensajes entre los elementos de procesamiento. Supone tenerpag=2d{\displaystyle p=2^{d}}Elementos de procesador (PE) que participan en el algoritmo igual al número de esquinas en un hipercubo d -dimensional .

Diferentes hipercubos para distintos números de nodos.

A lo largo del algoritmo, cada PE se considera una esquina en un hipercubo hipotético con conocimiento de la suma total de prefijos σ, así como de la suma de prefijos x de todos los elementos hasta sí mismo (de acuerdo con los índices ordenados entre los PE), ambos en su propio hipercubo.

  • El algoritmo comienza asumiendo que cada PE es el único vértice de un hipercubo de dimensión cero y, por lo tanto, σ y x son iguales a la suma de prefijos locales de sus propios elementos.
  • El algoritmo continúa unificando hipercubos adyacentes en una dimensión. Durante cada unificación, σ se intercambia y agrega entre los dos hipercubos, manteniendo la invariante de que todos los PE en las esquinas de este nuevo hipercubo almacenan la suma total de prefijos de este hipercubo unificado en su variable σ . Sin embargo, solo el hipercubo que contiene los PE con índice mayor también agrega este σ a su variable local x , manteniendo la invariante de que x solo almacena el valor de la suma de prefijos de todos los elementos en los PE con índices menores o iguales a su propio índice.

En un hipercubo d -dimensional con2d{\displaystyle 2^{d}}PE en las esquinas, el algoritmo debe repetirse d veces para tener el2d{\displaystyle 2^{d}}Los hipercubos de dimensión cero se unifican en un hipercubo de dimensión d . Suponiendo un modelo de comunicación dúplex donde la σ de dos PE adyacentes en diferentes hipercubos se puede intercambiar en ambas direcciones en un paso de comunicación, esto significad=registro2pag{\displaystyle d=\log _{2}p}empresas emergentes de comunicación.

i : = Índice del propio elemento procesador ( PE ) m : = suma de prefijos de los elementos locales de este PE d : = número de dimensiones del hipercubox = m ; // Invariante: La suma de prefijos hasta este PE en el subcubo actual σ = m ; // Invariante: La suma de prefijos de todos los elementos en el subcubo actualpara ( k = 0 ; k <= d -1 ; k ++ ) { y = σ @ PE ( i xor 2 ^ k ) // Obtener la suma total de prefijos del subcubo opuesto a lo largo de la dimensión k σ = σ + y // Agregar la suma de prefijos de ambos subcubosif ( i & 2 ^ k ) { x = x + y // Solo se agrega la suma del prefijo del otro subcubo, si este PE es el de mayor índice. } }

Tamaños de mensajes grandes: árbol binario en paralelo

El algoritmo de árbol binario segmentado [ 18 ] es otro algoritmo para plataformas de memoria distribuida que es especialmente adecuado para tamaños de mensajes grandes.

Al igual que el algoritmo del hipercubo, presupone una estructura de comunicación especial. Los elementos de procesamiento (EP) se organizan hipotéticamente en un árbol binario (por ejemplo, un árbol de Fibonacci) con numeración infija según su índice dentro de los EP. La comunicación en dicho árbol siempre se produce entre nodos padre e hijo.

La numeración infija garantiza que para cualquier PE j dado , los índices de todos los nodos alcanzables por su subárbol izquierdo[lj1]{\displaystyle \color {Azul}{[l\dots j-1]}}son menores que j y los índices[j+1r]{\displaystyle \color {Blue}{[j+1\dots r]}}de todos los nodos en el subárbol derecho son mayores que j . El índice del padre es mayor que cualquiera de los índices en el subárbol de PE j si PE j es un hijo izquierdo y menor si PE j es un hijo derecho. Esto permite el siguiente razonamiento:

Intercambio de información entre elementos de procesamiento durante la fase ascendente (azul) y descendente (roja) en el algoritmo de suma de prefijos de árbol binario en pipeline.
  • La suma del prefijo local[lj1]{\displaystyle \color {Azul}{\oplus [l\dots j-1]}}del subárbol izquierdo debe agregarse para calcular la suma del prefijo local de PE j[lj]{\displaystyle \color {Azul}{\oplus [l\dots j]}}.
  • La suma del prefijo local[j+1r]{\displaystyle \color {Blue}{\oplus [j+1\dots r]}}del subárbol derecho debe agregarse para calcular la suma de prefijos locales de PE h de nivel superior que se alcanzan en una ruta que contiene una conexión de hijos izquierdos (lo que significah>j{\displaystyle h>j}).
  • La suma total de prefijos[0j]{\displaystyle \color {Red}{\oplus [0\dots j]}}de PE j es necesario para calcular las sumas totales de prefijos en el subárbol derecho (por ejemplo[0jr]{\displaystyle \color {Red}{\oplus [0\dots j\dots r]}}para el nodo de índice más alto en el subárbol).
  • PE j debe incluir la suma total del prefijo[0l1]{\displaystyle \color {Red}{\oplus [0\dots l-1]}}del primer nodo de orden superior al que se llega a través de una ruta ascendente que incluye una conexión de hijos derechos para calcular su suma de prefijo total.

Nótese la distinción entre sumas de prefijos locales de subárbol y sumas totales de prefijos. Los puntos dos, tres y cuatro pueden llevar a creer que formarían una dependencia circular , pero este no es el caso. Los PE de nivel inferior podrían requerir la suma total de prefijos de los PE de nivel superior para calcular su suma total de prefijos, pero los PE de nivel superior solo requieren sumas de prefijos locales de subárbol para calcular su suma total de prefijos. El nodo raíz, como nodo de nivel más alto, solo requiere la suma de prefijos local de su subárbol izquierdo para calcular su propia suma de prefijos. Cada PE en la ruta desde PE 0 hasta el PE raíz solo requiere la suma de prefijos local de su subárbol izquierdo para calcular su propia suma de prefijos, mientras que cada nodo en la ruta desde PE p-1 (último PE) hasta el PE raíz requiere la suma total de prefijos de su padre para calcular su propia suma total de prefijos.

Esto da lugar a un algoritmo de dos fases:

Fase ascendente
Propagar la suma de prefijos locales del subárbol[ljr]{\displaystyle \color {Blue}{\oplus [l\dots j\dots r]}}a su padre para cada PE j .
Fase descendente
Propagar la suma total de prefijos exclusivos (PE j exclusivo , así como los PE en su subárbol izquierdo)[0l1]{\displaystyle \color {Red}{\oplus [0\dots l-1]}}de todos los PE de índice inferior que no están incluidos en el subárbol dirigido del PE j a los PE de nivel inferior en el subárbol hijo izquierdo del PE j . Propagar la suma de prefijos inclusivos[0j]{\displaystyle \color {Red}{\oplus [0\dots j]}}al subárbol hijo derecho de PE j .

Tenga en cuenta que el algoritmo se ejecuta en paralelo en cada PE y que los PE se bloquearán al recibir paquetes hasta que sus hijos/padres les proporcionen los mismos.

k := número de paquetes en un mensaje m de un PE m @ { izquierda , derecha , padre , este } := // Mensajes en los diferentes PEx = m @ este// Fase ascendente: Calcular sumas de prefijos locales de subárbol para j = 0 a k - 1 : // Pipelining: Para cada paquete de un mensaje si hasLeftChild : blocking receive m [ j ] @ left // Esto reemplaza el m[j] local con el m[j] recibido // Agregación de la suma de prefijos locales inclusivos de los PE de índice inferior x [ j ] = m [ j ] x [ j ]if hasRightChild : blocking receive m [ j ] @ right // No agregamos m[j] a la suma del prefijo local, ya que los hijos derechos son PE de índice superior send x [ j ] m [ j ] to parent else : send x [ j ] to parent// Fase descendente para j = 0 a k - 1 : m [ j ] @ this = 0if hasParent : blocking receive m [ j ] @ parent // Para un hijo izquierdo m[j] es la suma de prefijos exclusivos de los padres, para un hijo derecho la suma de prefijos inclusivos x [ j ] = m [ j ] x [ j ] send m [ j ] to left // La suma total de prefijos de todos los PE menores que este o cualquier PE en el subárbol izquierdo send x [ j ] to right // La suma total de prefijos de todos los PE menores o iguales que este PE
Tuberías

Si el mensaje m de longitud n se puede dividir en k paquetes y el operador ⨁ se puede usar en cada uno de los paquetes de mensaje correspondientes por separado, es posible el procesamiento en paralelo . [ 18 ]

Si el algoritmo se utiliza sin segmentación, siempre hay solo dos niveles (los PE emisores y los PE receptores) del árbol binario en funcionamiento mientras todos los demás PE están esperando. Si hay p elementos de procesamiento y se utiliza un árbol binario balanceado, el árbol tieneregistro2pag{\displaystyle \log _{2}p}niveles, la longitud del camino desdePAGmi0{\displaystyle PE_{0}}aPAGmiroot{\displaystyle PE_{\mathrm {raíz} }}es por lo tantoregistro2pag1{\displaystyle \log _{2}p-1}que representa el número máximo de operaciones de comunicación no paralelas durante la fase ascendente, asimismo, la comunicación en la ruta descendente también está limitada aregistro2pag1{\displaystyle \log _{2}p-1}startups. Suponiendo un tiempo de inicio de comunicación deTstart{\displaystyle T_{\mathrm {start} }}y un tiempo de transmisión byte a byte deTbytmi{\displaystyle T_{\mathrm {byte} }}, las fases ascendente y descendente se limitan a(2registro2pag2)(Tstart+norteTbytmi){\displaystyle (2\log _{2}p-2)(T_{\mathrm {start} }+n\cdot T_{\mathrm {byte} })}en un escenario sin procesamiento en paralelo.

Al dividirse en k paquetes, cada uno de tamañonortek{\displaystyle {\tfrac {n}{k}}}y enviándolos por separado, el primer paquete aún necesita(registro2pag1)(Tstart+nortekTbytmi){\displaystyle (\log _{2}p-1)\left(T_{\mathrm {start} }+{\frac {n}{k}}\cdot T_{\mathrm {byte} }\right)}ser propagado aPAGmiroot{\displaystyle PE_{\mathrm {raíz} }}como parte de una suma de prefijo local y esto volverá a ocurrir para el último paquete sik>registro2pag{\displaystyle k>\log _{2}p}Sin embargo, entretanto, todos los PE a lo largo de la ruta pueden trabajar en paralelo y cada tercera operación de comunicación (recibir izquierda, recibir derecha, enviar al padre) envía un paquete al siguiente nivel, de modo que una fase puede completarse en2registro2pag1+3(k1){\displaystyle 2\log _{2}p-1+3(k-1)}operaciones de comunicación y ambas fases juntas necesitan(4registro2pag2+6(k1))(Tstart+nortekTbytmi){\displaystyle (4\cdot \log _{2}p-2+6(k-1))\left(T_{\mathrm {start} }+{\frac {n}{k}}\cdot T_{\mathrm {byte} }\right)}lo cual es favorable para tamaños de mensaje grandes n .

El algoritmo se puede optimizar aún más utilizando comunicación dúplex completo o en modelo telefónico y superponiendo la fase ascendente y la descendente. [ 18 ]

Estructuras de datos

Cuando un conjunto de datos puede actualizarse dinámicamente, puede almacenarse en una estructura de datos de árbol de Fenwick . Esta estructura permite tanto la búsqueda de cualquier valor de suma de prefijo individual como la modificación de cualquier valor de matriz en tiempo logarítmico por operación. [ 19 ] Sin embargo, un artículo anterior de 1982 [ 20 ] presenta una estructura de datos llamada Árbol de sumas parciales (véase la Sección 5.1) que parece superponerse a los árboles de Fenwick; en 1982 el término suma de prefijo aún no era tan común como lo es hoy.

Para matrices de dimensiones superiores, la tabla de áreas sumadas proporciona una estructura de datos basada en sumas de prefijos para calcular sumas de submatrices rectangulares arbitrarias. Esto puede ser una primitiva útil en operaciones de convolución de imágenes . [ 21 ]

Aplicaciones

El algoritmo de ordenación por conteo es un algoritmo de ordenación de enteros que utiliza la suma de prefijos de un histograma de frecuencias de claves para calcular la posición de cada clave en el array de salida ordenado. Se ejecuta en tiempo lineal para claves enteras menores que el número de elementos y se utiliza frecuentemente como parte de la ordenación por radix , un algoritmo rápido para ordenar enteros con menor restricción de magnitud. [ 1 ]

La clasificación de listas , el problema de transformar una lista enlazada en un arreglo que representa la misma secuencia de elementos, puede verse como el cálculo de una suma de prefijos en la secuencia 1, 1, 1, ... y luego el mapeo de cada elemento a la posición del arreglo dada por el valor de su suma de prefijos; al combinar la clasificación de listas, las sumas de prefijos y los recorridos de Euler , muchos problemas importantes sobre árboles pueden resolverse mediante algoritmos paralelos eficientes. [ 4 ]

Una de las primeras aplicaciones de los algoritmos de suma de prefijos paralelos fue el diseño de sumadores binarios , circuitos booleanos que pueden sumar dos números binarios de n bits. En esta aplicación, la secuencia de bits de acarreo de la suma se puede representar como una operación de escaneo sobre la secuencia de pares de bits de entrada, utilizando la función de mayoría para combinar el acarreo anterior con estos dos bits. Cada bit del número de salida se puede encontrar como la operación OR exclusiva de dos bits de entrada con el bit de acarreo correspondiente. Al utilizar un circuito que realiza las operaciones del algoritmo de suma de prefijos paralelo, es posible diseñar un sumador que utiliza O ( n ) compuertas lógicas y O (log n ) pasos de tiempo. [ 3 ] [ 11 ] [ 12 ]

En el modelo de computación de máquina de acceso aleatorio paralelo , las sumas de prefijos se pueden usar para simular algoritmos paralelos que asumen la capacidad de múltiples procesadores para acceder a la misma celda de memoria al mismo tiempo, en máquinas paralelas que prohíben el acceso simultáneo. Mediante una red de ordenación , un conjunto de solicitudes de acceso a memoria paralelas se puede ordenar en una secuencia de manera que los accesos a la misma celda sean contiguos dentro de la secuencia; luego se pueden usar operaciones de escaneo para determinar cuáles de los accesos tienen éxito al escribir en las celdas solicitadas y para distribuir los resultados de las operaciones de lectura de memoria a múltiples procesadores que solicitan el mismo resultado. [ 22 ]

En la tesis doctoral de Guy Blelloch , [ 23 ] las operaciones de prefijo paralelas forman parte de la formalización del modelo de paralelismo de datos proporcionado por máquinas como Connection Machine . Connection Machine CM-1 y CM-2 proporcionaron una red hipercúbica en la que se podía implementar el Algoritmo 1 anterior, mientras que CM-5 proporcionó una red dedicada para implementar el Algoritmo 2. [ 24 ]

En la construcción de códigos Gray , secuencias de valores binarios con la propiedad de que los valores consecutivos de la secuencia difieren entre sí en una sola posición de bit, un número n puede convertirse en el valor del código Gray en la posición n de la secuencia simplemente tomando la operación OR exclusiva de n y n /2 (el número formado al desplazar n a la derecha una posición de bit). La operación inversa, decodificar un valor codificado en Gray x en un número binario , es más compleja, pero puede expresarse como la suma de prefijos de los bits de x , donde cada operación de suma dentro de la suma de prefijos se realiza módulo dos. Una suma de prefijos de este tipo puede realizarse de manera eficiente utilizando las operaciones booleanas bit a bit disponibles en las computadoras modernas, calculando la operación OR exclusiva de x con cada uno de los números formados al desplazar x a la izquierda un número de bits que es potencia de dos. [ 25 ] 

El prefijo paralelo (que utiliza la multiplicación como operación asociativa subyacente) también puede emplearse para construir algoritmos rápidos para la interpolación polinómica paralela . En particular, puede utilizarse para calcular los coeficientes de diferencias divididas de la forma de Newton del polinomio de interpolación. [ 26 ] Este enfoque basado en prefijos también puede emplearse para obtener las diferencias divididas generalizadas para la interpolación de Hermite (confluente) , así como para algoritmos paralelos para sistemas de Vandermonde . [ 27 ]

Los algoritmos de prefijo paralelo también pueden utilizarse para la paralelización temporal de métodos de estimación bayesiana recursiva , incluidos los filtros bayesianos, los filtros de Kalman , así como los suavizadores correspondientes. [ 28 ] La idea central es que, por ejemplo, las soluciones a los problemas de filtrado bayesiano/de Kalman se escriben en términos de un operador de filtrado asociativo adecuadamente definido , de modo que las "sumas" de prefijo del operador de filtrado dan la solución de filtrado. Esto permite que los algoritmos de prefijo paralelo se apliquen para calcular las soluciones de filtrado y suavizado. Una idea similar también funciona para la paralelización de una clase de solucionadores de ecuaciones diferenciales probabilísticas [ 29 ] en el contexto de la numérica probabilística .

En el contexto del control óptimo , se pueden utilizar algoritmos de prefijo paralelo para la paralelización de la ecuación de Bellman y las ecuaciones de Hamilton-Jacobi-Bellman (ecuaciones HJB), incluyendo sus casos especiales de regulador lineal-cuadrático . [ 30 ] [ 31 ] Aquí, la idea es que podemos definir un operador asociativo para una combinación de funciones de valor condicional (condicionadas al punto final), y las sumas de prefijo de este operador dan soluciones a las ecuaciones de Bellman o HJB.

La suma de prefijos se utiliza para el balanceo de carga como un algoritmo de bajo costo para distribuir el trabajo entre múltiples procesadores, donde el objetivo principal es lograr una cantidad igual de trabajo en cada procesador. El algoritmo utiliza una matriz de pesos que representan la cantidad de trabajo requerida para cada elemento. Después de calcular la suma de prefijos, el elemento de trabajo i se envía para su procesamiento a la unidad de procesamiento con el número [ prefixSumValue i / totalWork / numberOfProcessors ] . [ 32 ] Gráficamente, esto corresponde a una operación donde la cantidad de trabajo en cada elemento está representada por la longitud de un segmento lineal, todos los segmentos se colocan secuencialmente en una línea y el resultado se divide en un número de piezas, correspondiente al número de procesadores. [ 33 ]

A continuación se muestra una tabla de consulta de cuartos de cuadrado con el resto descartado para los dígitos del 0 al 18; esto permite la multiplicación de números hasta 9×9 .

Por ejemplo, si quisieras multiplicar 9 por 3, observarías que la suma y la diferencia son 12 y 6 respectivamente. Al buscar ambos valores en la tabla, obtendrías 36 y 9, cuya diferencia es 27, que es el producto de 9 y 3.

Véase también

Referencias

  1. 1 2 Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford (2001), Introducción a los algoritmos (2.ª  ed.), MIT Press y McGraw-Hill , págs. 168–170 , ISBN  0-262-03293-7.
  2. Cole, Richard; Vishkin, Uzi (1986), "Lanzamiento de moneda determinista con aplicaciones a la clasificación óptima de listas paralelas" (PDF) , Information and Control , 70 (1): 32–53 , doi : 10.1016/S0019-9958(86)80023-7
  3. 1 2 3 4 5 Ladner, RE; Fischer, MJ (1980), "Parallel Prefix Computation", Journal of the ACM , 27 (4): 831– 838, CiteSeerX 10.1.1.106.6247 , doi : 10.1145/322217.322232 , MR 0594702 , S2CID 207568668   .
  4. ^ Tarjan , Robert E .; Vishkin, Uzi (1985), "Un algoritmo eficiente de biconectividad paralela", SIAM Journal on Computing , 14 (4): 862– 874, CiteSeerX 10.1.1.465.8898 , doi : 10.1137/0214061 .
  5. Lakshmivarahan, S.; Dhall, SK (1994), Parallelism in the Prefix Problem , Oxford University Press , ISBN 0-19508849-2.
  6. Blelloch, Guy (2011), Sumas de prefijos y sus aplicaciones (Apuntes de clase) (PDF) , Universidad Carnegie Mellon.
  7. Callahan, Paul; Kosaraju, S. Rao (1995), "Una descomposición de conjuntos de puntos multidimensionales con aplicaciones a k-vecinos más cercanos y campos potenciales de n cuerpos", Journal of the ACM , 42 (1): 67–90 , doi : 10.1145/200836.200853 , S2CID 1818562 .
  8. "GPU Gems 3" .
  9. Hillis, W. Daniel; Steele, Jr., Guy L. (diciembre de 1986). "Algoritmos de datos en paralelo" . Communications of the ACM . 29 (12): 1170– 1183. doi : 10.1145/7902.7903 .
  10. Owens, John D.; Luebke, David; Govindaraju, Naga; Harris, Mark; Krüger, Jens; Lefohn, Aaron E.; Purcell, Timothy J. (2007). "Un estudio sobre computación de propósito general en hardware gráfico" (PDF) . Computer Graphics Forum . 26 (1): 80– 113. doi : 10.1111/j.1467-8659.2007.01012.x .
  11. 1 2 Ofman, Yu. (1962), Об алгоритмической сложности funciones de disco, Doklady Akademii Nauk SSSR (en ruso), 145 (1): 48– 51, MR 0168423 . Traducción al inglés, "Sobre la complejidad algorítmica de las funciones discretas", Soviet Physics Doklady 7 : 589–591 1963.
  12. 1 2 Khrapchenko, VM (1967), "Estimación asintótica del tiempo de suma de un sumador paralelo", Problemy Kibernet. (en ruso), 19 : 107– 122. Traducción al inglés en Syst. Theory Res. 19 ; 105–122, 1970.
  13. Sengupta, Shubhabrata; Harris, Mark; Zhang, Yao; Owens, John D. (2007). Primitivas de escaneo para computación GPU . Actas del 22.º Simposio ACM SIGGRAPH/EUROGRAPHICS sobre hardware gráfico. págs. 97–106 . Archivado del original el 3 de septiembre de 2014. Consultado el 29 de noviembre de 2007 . 
  14. Vishkin, Uzi (2003). Sumas de prefijo y una aplicación de las mismas . Patente estadounidense 6,542,918.
  15. Singler, Johannes. "MCSTL: La biblioteca de plantillas estándar multinúcleo" . Consultado el 29 de marzo de 2019 .
  16. Singler, Johannes; Sanders, Peter; Putze, Felix (2007). "MCSTL: La biblioteca de plantillas estándar multinúcleo". Procesamiento paralelo Euro-Par 2007. Notas de clase en informática. Vol. 4641. págs. 682–694 . doi : 10.1007/978-3-540-74466-5_72 . ISBN   978-3-540-74465-8ISSN 0302-9743 
  17. ^ Ananth Grama; Vipin Kumar; Anshul Gupta (2003). Introducción a la Computación Paralela . Addison-Wesley. págs.85 , 86. ISBN  978-0-201-64865-2.
  18. 1 2 3 Sanders, Peter; Träff, Jesper Larsson (2006). "Algoritmos de prefijo paralelo (escaneo) para MPI". Avances recientes en máquinas virtuales paralelas e interfaz de paso de mensajes . Notas de clase en ciencias de la computación. Vol. 4192. págs. 49–57 . doi : 10.1007/11846802_15 . ISBN   978-3-540-39110-4ISSN 0302-9743 
  19. Fenwick, Peter M. (1994), "Una nueva estructura de datos para tablas de frecuencia acumulativa", Software: Practice and Experience , 24 (3): 327–336 , doi : 10.1002/spe.4380240306 , S2CID 7519761 
  20. Shiloach, Yossi; Vishkin, Uzi (1982b), "Un algoritmo paralelo de flujo máximo O ( n 2 log n )", Journal of Algorithms , 3 (2): 128– 146, doi : 10.1016/0196-6774(82)90013-X  
  21. Szeliski, Richard (2010), "Summed area table (integral image)", Computer Vision: Algorithms and Applications, Texts in Computer Science, Springer, pp. 106–107, ISBN 9781848829350.
  22. Vishkin, Uzi (1983), "Implementation of simultaneous memory address access in models that forbid it", Journal of Algorithms, 4 (1): 45–50, doi:10.1016/0196-6774(83)90033-0, MR 0689265.
  23. Blelloch, Guy E. (1990). Vector models for data-parallel computing. Cambridge, MA: MIT Press. ISBN 026202313X. OCLC 21761743.
  24. Leiserson, Charles E.; Abuhamdeh, Zahi S.; Douglas, David C.; Feynman, Carl R.; Ganmukhi, Mahesh N.; Hill, Jeffrey V.; Hillis, W. Daniel; Kuszmaul, Bradley C.; St. Pierre, Margaret A. (March 15, 1996). "The Network Architecture of the Connection Machine CM-5". Journal of Parallel and Distributed Computing. 33 (2): 145–158. doi:10.1006/jpdc.1996.0033. ISSN 0743-7315.
  25. Warren, Henry S. (2003), Hacker's Delight, Addison-Wesley, p. 236, ISBN 978-0-201-91465-8.
  26. Eğecioğlu, O.; Gallopoulos, E.; Koç, C. (1990), "A parallel method for fast and practical high-order Newton interpolation", BIT Computer Science and Numerical Mathematics, 30 (2): 268–288, doi:10.1007/BF02017348, S2CID 9607531.
  27. Eğecioğlu, O.; Gallopoulos, E.; Koç, C. (1989), "Fast computation of divided differences and parallel Hermite interpolation", Journal of Complexity, 5 (4): 417–437, doi:10.1016/0885-064X(89)90018-6
  28. Särkkä, Simo; García-Fernández, Ángel F. (2021). "Temporal Parallelization of Bayesian Smoothers". IEEE Transactions on Automatic Control. 66 (1): 299–306. arXiv:1905.13002. Bibcode:2021ITAC...66..299S. doi:10.1109/TAC.2020.2976316.
  29. ^ Bosco, Natanael; Corenflos, Adrián; Yaghoobi, Fatemeh; Tronarp, Filip; Hennig, Philipp; Särkkä, Simo (2024). "Solucionadores de EDO numéricos probabilísticos en tiempo paralelo" . Revista de investigación sobre aprendizaje automático . 25 . arXiv : 2310.01145 .
  30. Särkkä, Simo; García-Fernández, Ángel F. (2023). "Paralelización temporal de programación dinámica y control lineal cuadrático" . IEEE Transactions on Automatic Control . 68 (2): 851– 866. arXiv : 2104.03186 . Bibcode : 2023ITAC...68..851S . doi : 10.1109/TAC.2022.3147017 .
  31. Särkkä, Simo; García-Fernández, Ángel F. (2025). "Paralelización temporal de la ecuación HJB y control lineal cuadrático en tiempo continuo" . IEEE Transactions on Automatic Control . 70 (6): 3755– 3770. arXiv : 2212.11744 . Bibcode : 2025ITAC...70.3755S . doi : 10.1109/TAC.2024.3518309 .
  32. Becker, Aaron; Zheng, Gengbin; Kalé, Laxmikant V. (2011). "Load Balancing, Distributed Memory". Encyclopedia of Parallel Computing . Boston, MA: Springer US. p. 1046. doi : 10.1007/978-0-387-09766-4_504 . ISBN  978-0-387-09765-7.
  33. Sanders, Peter; Mehlhorn, Kurt; Dietzfelbinger, Martin; Dementiev, Roman (2019). «Load Balancing» (PDF) . Sequential and Parallel Algorithms and Data Structures . Cham: Springer International Publishing. pp. 419–434 . doi : 10.1007/978-3-030-25209-0_14 . ISBN  978-3-030-25208-3.