Parallelize nested for loop with openMP
It is not possible to reduce an array or an struct in OpenMP, which is mentioned here: https://computing.llnl.gov/tutorials/openMP/#REDUCTION.
I think you can declare multiple copies of histogram
, each of which is used in one thread. After then use another OpenMP loop to add them up.
seb
Updated on July 10, 2022Comments
-
seb almost 2 years
I am trying to optimize the nested for loop in the function generate_histogram() below with openMP. I have tried around a lot with different combinations of pragmas based on what I've read in this SE post.
The problem is that the nested for loop performs faster without openMP than with openMP!
If I try to parallelize my code with reduction instead of the atomic pragma, I end up with netchunk fails. Does anybody know a fancy tweak for this one? I am trying to bin data into a histogram. So the histogram is variable in size in the real code, unlike in the snippet below.
#include<stdio.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #define float_t float #include <time.h> #include <omp.h> float_t generate_histogram(float_t **matrix, int *histogram, int mat_size, int hist_size) { int i,j,k,count; float_t max = 0.; float_t sum; //set histogram to zero everywhere for(i = 0; i < hist_size; i++) histogram[i] = 0; //matrix computations #pragma omp parallel for private(i) shared(histogram,j,k,max) schedule(dynamic) //#pragma omp parallel for schedule(runtime) for (i = 1; i < (mat_size-1); i++) { #pragma omp parallel for private(j,k) shared(histogram,max) schedule(dynamic) //pragma omp prallel for schedule(dynamic) for(j = 1; j < (mat_size-1); j++) { //assign current matrix[i][j] to element in order to reduce memory access sum = fabs(matrix[i][j]-matrix[i-1][j]) + fabs(matrix[i][j] - matrix[i+1][j]) + fabs(matrix[i][j]-matrix[i][j-1]) + fabs(matrix[i][j] - matrix[i][j+1]); //compute index of histogram bin k = (int)(sum * (float)mat_size); #pragma omp atomic histogram[k] += 1; //keep track of largest element if(sum > max) max = sum; }//end inner for }//end outer for return max; } main() { int i,j,N,boxes; N = 10000; float_t **matrix; int* histogram; boxes = N / 2; //allocate a matrix with some numbers matrix = calloc(N, sizeof(float_t **)); for(i = 0; i < N; i++) matrix[i] = calloc(N, sizeof(float_t *)); for(i = 0; i < N; i++) for(j = 0; j < N; j++) matrix[i][j] = 1./(float_t) N * (float_t) i; histogram = malloc(boxes * sizeof(int)); generate_histogram(matrix, histogram, N, boxes); }