Paralléliser imbriqués pour la boucle avec openMP
Je suis en train d'optimiser le imbriqués pour la boucle dans la fonction generate_histogram() ci-dessous avec openMP. J'ai essayé beaucoup avec les différentes combinaisons de pragmas fondée sur ce que j'ai lu dans cela SE post.
Le problème est que le imbriqués pour la boucle effectue plus rapidement sans openMP qu'avec openMP!
Si j'essaie de paralléliser mon code avec réduction de la place de la atomique pragma, je me retrouve avec netchunk échoue. Quelqu'un sait d'une fantaisie tweak pour ce que c'est? Je suis en train de données d'emplacement dans un histogramme. Ainsi, le histogramme est de taille variable dans le code réel, contrairement à l'extrait ci-dessous.
#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);
}
J'ai édité. Désolé, c'était totalement flou. Mieux maintenant?
OriginalL'auteur seb | 2013-05-25
Vous devez vous connecter pour publier un commentaire.
C'est un problème intéressant. J'ai corrigé ton code. @KunHuang avait la bonne idée, mais vous avez plusieurs problèmes avec la vie privée et des variables partagées.
Votre ancienne fonction est appelée
generate_histogram
dont j'ai commenté l'omp choses. La nouvelle qui utilise OpenMP est appelégenerate_histogram_omp
.L'ancien code se termine dans le temps 0.67 secondes sur mon système (ivy bridge dual core) et le nouveau code se termine dans 0.32 secondes.
Aussi, j'ai essayé de fusion de votre boucle, mais il a réalisé la performance bien pire (sans doute un problème de cache) donc je ne paralléliser la première boucle et je reçois toujours une vitesse 2x sur deux cores avec le code actuel, de toute façon. J'ai quitté la fusion de code en commentaire si vous voulez jouer avec elle.
Enfin, vos valeurs initiales de la matrice ne sont pas vraiment remplir l'histogramme beaucoup c'est à dire seulement quelques bacs sont remplis.
J'ai compilé avec
Le code:
OriginalL'auteur
Il n'est pas possible de réduire d'un tableau ou d'une structure dans OpenMP, qui est mentionné ici: https://computing.llnl.gov/tutorials/openMP/#REDUCTION.
Je pense que vous pouvez déclarer plusieurs copies de
histogram
, chacun de qui est utilisée dans un thread. Après avoir ensuite utiliser un autre OpenMP boucle de l'ajouter.OriginalL'auteur konjac