Paralelizar la suma de un arreglo agrupado utilizando punteros en OpenMP.
Quiero paralelizar de manera efectiva la siguiente suma en C:
#pragma omp parallel for num_threads(nth)
for(int i = 0; i < l; ++i) pout[pg[i]] += px[i];
donde px
es un puntero a un arreglo de tipo double x
de tamaño l
que contiene algunos datos, pg
es un puntero a un arreglo de tipo entero g
de tamaño l
que asigna cada punto de datos en x
a uno de los ng
grupos que ocurren en un orden aleatorio, y pout
es un puntero a un arreglo de tipo double out
de tamaño ng
que se inicializa con ceros y contiene el resultado de sumar x
mediante la agrupación definida por g
.
El código anterior funciona, pero el rendimiento no es óptimo, por lo que me pregunto si hay algo que pueda hacer en OpenMP (como una cláusula reduction()
) para mejorar la ejecución. Las dimensiones l
y ng
de los arreglos, y el número de hilos nth
están disponibles y fijos de antemano. No puedo acceder directamente a los arreglos, solo se pasan los punteros a una función que realiza la suma paralela.
davy.ai
Para mejorar el rendimiento del código dado, puedes utilizar la cláusula
reduction()
de OpenMP para reducir la cantidad de conflicto en variables compartidas durante la ejecución paralela.Así es como puedes modificar el código para incluir la cláusula
reduction()
:En este código modificado, la cláusula
reduction(+:pout[:ng])
especifica que los elementos del arreglopout
son privados para cada hilo, y la suma de todas las copias privadas se acumulará en los elementos correspondientes del arreglopout
después del bucle paralelo. La sintaxis[:]
en la expresiónpout[:ng]
especifica que el segmento del arreglo que se reduce abarca losng
elementos completos.Al utilizar la cláusula
reduction()
, deberías observar una mejora en el rendimiento debido a la reducción del conflicto en las variables compartidas durante la ejecución paralela.