Ich habe versucht, in einem Array von Doppelpunkten auf parallele Weise mit OpenMP zu schreiben (zu aktualisieren). Die Idee ist, dass das Element, das aktualisiert werden muss, mehrmals aktualisiert werden kann und das Element selbst während des Betriebs berechnet wird. Dies macht es sehr anfällig für Race-Bedingungen, es sei denn, ich "sperre" den Speicherbereich entsprechend dem Element, das mit einer atomaren Operation aktualisiert wird. Als Beispiel unten:Aktualisieren von Double-Arrays mit atomaren Operationen
#include<omp.h>
#include<stdlib.h>
int main()
{
double *x=NULL, contribution = 1234.5;
size_t xlen=1000, i, n;
if ((x = (double *) calloc(xlen,sizeof(double))) == NULL) exit(-1)
#pragma omp parallel for shared(x) private(n,contribution)
for (i=0; i<xlen; i++) {
n = find_n_on_the_fly(i);
#pragma omp atomic update
x[n]+=contribution; // in the more complicated case contributions are different
}
return 0;
}
Ich renne mit diesem Ansatz immer noch in Rennbedingungen. Ich habe versucht, kritische Abschnitte zu verwenden, aber es tötet mich vollständig, da die Arrays groß sind und die Anzahl der Updates ebenfalls groß ist.
Frage: Was ist falsch an diesem Ansatz? Gibt es einen besseren Weg, damit umzugehen?
Hinweis: Um dies zu tun, mache ich etwas Dummes, indem ich Kopien der Arrays für jeden der Threads erstelle und sie später reduziere. Aber Speicherbeschränkungen erlauben mir nicht, weiter zu gehen.
Warum nicht eine Liste von 'n' /' contribution'-Paaren erstellen und weiter in sie hineinschieben und sie dann in 'x' Array oder irgendeine andere Art von spärlicher Repräsentation reduzieren? – user3528438
@ user3528438 Das ist eine Idee und steht im Einklang mit meiner Notiz. Haben Sie ein konkretes Arbeitsbeispiel, das nicht auf das reduziert, was ich gerade mache? –
Per Definition ist eine atomare Operation für einen 64-Bit-Wert nur mit einer 64-Bit (oder höher) Hardware-Architektur möglich. Die Fließkomma-Bibliothek befindet sich möglicherweise an der Wurzel des Problems, das Sie hier sehen. Haben Sie versucht, zu "unsigned long long" zu tippen? Außerdem wäre eine Hash-Tabelle viel schneller zum Nachschlagen von Array-Elementen, anstatt für jedes Element eine Schleife zu durchsuchen. –