Parallelisieren geschachtelte for-Schleife mit openMP
Ich versuche zur Optimierung der verschachtelten for-Schleife in der Funktion generate_histogram() unten mit openMP. Ich habe versucht, viel mit verschiedenen Kombinationen von pragmas, basierend auf was ich gelesen habe, in diese SE post.
Das problem ist, dass die geschachtelte for-Schleife führt schneller ohne openMP als mit openMP!
Wenn ich versuche, Sie zu parallelisieren mein code mit der Reduktion statt der atomic pragma, dass ich am Ende mit netchunk ausfällt. Weiß jemand ein schickes tweak für diese ein? Ich bin versucht bin, die Daten in einem Histogramm. Also die Histogramm ist variabel in der Größe, die in der realen code, anders als in dem snippet unten.
#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);
}
- Was meinst du mit doppelt? Ich kann nicht schnappen Sie Zweck.
- Ich habe bearbeitet es. Sorry, es war völlig unklar. Jetzt besser?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist ein Interessantes problem. Ich fixierte Ihren code. @KunHuang hatte die richtige Idee, aber Sie haben noch mehrere Probleme mit gemeinsamen und privaten Variablen.
Ihre alte Funktion aufgerufen wird
generate_histogram
in die ich auskommentiert, die omp-Zeug. Die neue, die verwendet OpenMP genanntgenerate_histogram_omp
.Der alte code endet in der Zeit von 0,67 Sekunden auf meinem system (ivy bridge dual-core) und den neuen code endet in 0.32 Sekunden.
Auch, ich habe versucht, die Fixierung der Schleife, aber es machte die Leistung noch viel schlimmer (vermutlich ein cache-Problem), so dass ich nur parallelisieren, die erste Schleife und ich bekomme immer noch ein 2x-speed bis auf zwei Kerne mit der aktuellen code-sowieso. Ich verließ das fusionierte code auskommentiert, wenn Sie möchten, um mit ihm zu spielen.
Schließlich Ihre ursprünglichen Werte der matrix nicht wirklich füllen Sie das Histogramm viel also nur ein paar Kisten gefüllt.
Den ich kompiliert habe, mit
Code:
Es ist nicht möglich, um ein array oder ein struct in OpenMP, die hier erwähnt wird: https://computing.llnl.gov/tutorials/openMP/#REDUCTION.
Ich denke, Sie können erklären, mehrere Kopien von
histogram
, von denen jeder verwendet wird, in einen thread. Nachdem Sie dann eine andere OpenMP-Schleife fügen Sie Sie.