Parallelisierung mit OpenMP
-
Hallo,
ich bin gerade dabei ein paar Funktionen mittels OpenMP zu parallelisieren. Bei einigen habe ich an sich keine großen Probleme, wie bspw.:
[...] omp_set_num_threads(4); #pragma omp parallel for for (int y = 0; y < height; y++) { greyBuf[y] = new uchar[width + k.width - 1]; memcpy(greyBuf[y], grey[y], width); } /* * apply kernel on pixmap * give a special treatment for the border **/ // border-top int x; #pragma omp parallel for private(x) for (int y = 0; y < (k.width / 2); y++) { for (x = 0; x < width; x++) { grey[y][x] = falten(x, y, k, greyBuf); } } [...] #pragma omp parallel for for (int i = 0; i < height; i++) delete [] greyBuf[i]; [...]Nun habe ich aber einige Probleme bei der Parallelisierung eines Histogramms:
[...] #pragma omp parallel for private(x) for (int y = 0; y < height; y++) { for (x = 0; x < width; x++) { #pragma omp atomic histoRed[red[y][x]]++; #pragma omp atomic histoGreen[green[y][x]]++; #pragma omp atomic histoBlue[blue[y][x]]++; } } [...]So ist das ganze allerdings wesentlich langsamer als die nich nicht parallelisierte Version. Eigentlich müsste ja aber nur der Zugriff auf die Einzelnen Arrayelement synchronisiert werden. Auf verschiedene Elemente eines Arrays darf ja parallel zugegriffen werden. Jedoch ist mir bisher kein Weg eingefallen, wie man das realisieren könnte. Ich hoffe, es hat jmd. ein wenig mehr Ahnung von OpenMP und kann mir ein paar Tipps geben.
Gruß Lars
-
der code ist nicht vernuenftig parallelisierbar so.
uU macht openMP das ohne dediziertes lock und ueber CAS - so genau kenne ich die implementierung nicht. Das problem dabei bleibt aber bestehen: locking kostet zeit. Und jede operation in deiner schleife muss gelockt werden.
was uU etwas bringen koennte waere 3 schleife zu machen die parallel laufen und jeweils nur red, green oder blue setzen.
-
Nur nochmal hier meine Lösung. Ich habe das ganze letztendlich wirklich in drei Blöcke zerlegt:
omp_set_num_threads(3); #pragma omp parallel { #pragma omp single nowait { int histoRed[256] = {0}; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { histoRed[red[y][x]]++; } } ofstream outRed("parallel_red_histogramm.dat", ofstream::out); for (int i = 0; i < 256; i++) outRed << i << ' ' << histoRed[i] << endl; outRed.close(); } #pragma omp single nowait { // same for green } #pragma omp single nowait { // and for blue } }