Die OpenMP-Funktion ruft parallel
Ich bin auf der Suche nach einer Möglichkeit eine Funktion aufzurufen, die in parallel.
Zum Beispiel, wenn ich 4 threads, möchte ich jeden von Ihnen auf Aufruf der gleichen Funktion mit Ihren eigene thread-id als argument.
Weil der Streit, kein thread werden, arbeiten auf den gleichen Daten.
#pragma omp parallel
{
for(int p = 0; p < numberOfThreads; p++)
{
if(p == omp_get_thread_num())
parDF(p);
}
}
Faden 0 ausgeführt werden soll parDF(0)
Thread 1 ausgeführt werden soll parDF(1)
Thread 2 ausgeführt werden soll parDF(2)
Thread 3 laufen sollte parDF(3)
All dies sollte getan werden, zur gleichen Zeit...
Diese (offensichtlich) nicht funktioniert, aber was ist der richtige Weg, um parallele Funktionsaufrufe?
EDIT: Der eigentliche code (Dies könnte zu viele Informationen... Aber es war gefragt...)
Aus der Funktion, die Anrufe parDF():
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
numberOfThreads = omp_get_num_threads();
//split nodeQueue
#pragma omp master
{
splitNodeQueue(numberOfThreads);
}
int tid = omp_get_thread_num();
//printf("Hello World from thread = %d\n", tid);
#pragma omp parallel for private(tid)
for(int i = 0; i < numberOfThreads; ++i)
{
parDF(tid, originalQueueSize, DFlevel);
}
}
Den parDF Funktion:
bool Tree::parDF(int id, int originalQueueSize, int DFlevel)
{
double possibilities[20];
double sequence[3];
double workingSequence[3];
int nodesToExpand = originalQueueSize/omp_get_num_threads();
int tenthsTicks = nodesToExpand/10;
int numPossibilities = 0;
int percentage = 0;
list<double>::iterator i;
list<TreeNode*>::iterator n;
cout << "My ID is: "<< omp_get_thread_num() << endl;
while(parNodeQueue[id].size() > 0 and parNodeQueue[id].back()->depth == DFlevel)
{
if(parNodeQueue[id].size()%tenthsTicks == 0)
{
cout << endl;
cout << percentage*10 << "% done..." << endl;
if(percentage == 10)
{
percentage = 0;
}
percentage++;
}
//countStartPoints++;
depthFirstQueue.push_back(parNodeQueue[id].back());
numPossibilities = 0;
for(i = parNodeQueue[id].back()->content.sortedPoints.begin(); i != parNodeQueue[id].back()->content.sortedPoints.end(); i++)
{
for(int j = 0; j < deltas; j++)
{
if(parNodeQueue[id].back()->content.doesPointExist((*i) + delta[j]))
{
for(int k = 0; k <= numPossibilities; k++)
{
if(fabs((*i) + delta[j] - possibilities[k]) < 0.01)
{
goto pointAlreadyAdded;
}
}
possibilities[numPossibilities] = ((*i) + delta[j]);
numPossibilities++;
pointAlreadyAdded:
continue;
}
}
}
//Out of the list of possible points. All combinations of 3 are added, building small subtrees in from the node.
//If a subtree succesfully breaks the lower bound, true is returned.
for(int i = 0; i < numPossibilities; i++)
{
for(int j = 0; j < numPossibilities; j++)
{
for(int k = 0; k < numPossibilities; k++)
{
if( k != j and j != i and i != k)
{
sequence[0] = possibilities[i];
sequence[1] = possibilities[j];
sequence[2] = possibilities[k];
//countSeq++;
if(addSequence(sequence, id))
{
//successes++;
workingSequence[0] = sequence[0];
workingSequence[1] = sequence[1];
workingSequence[2] = sequence[2];
parNodeQueue[id].back()->workingSequence[0] = sequence[0];
parNodeQueue[id].back()->workingSequence[1] = sequence[1];
parNodeQueue[id].back()->workingSequence[2] = sequence[2];
parNodeQueue[id].back()->live = false;
succesfulNodes.push_back(parNodeQueue[id].back());
goto nextNode;
}
else
{
destroySubtree(parNodeQueue[id].back());
}
}
}
}
}
nextNode:
parNodeQueue[id].pop_back();
}
- Vergessen Sie nicht, kompilieren Sie und verknüpfen Sie mit OpenMP :
-fopenmp
mitgcc
. - Ich würde nicht verwenden Sie die Zeile
if(p == omp_get_thread_num())
wie OpenMP erhält automatisch die zur Verfügung threads zu arbeiten, um auf das innere der Schleife. Sie sollte sich keine Gedanken über die Anzahl der tatsächlichen thread-computing-Daten : was passiert, wenn du nur 2 threads zur Verfügung ? Sie wird nie eine echte mitp == omp_get_thread_num()
für p = 2 oder 3, dann die Schleife ausgeführt wird vier mal durch die thread-Nummer 0 und Nummer 1. Damit Sie nicht immer anrufen parDF(2) und parDF(3).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist das, was Sie nach sind?
Live Auf Coliru
Ausgabe:
num_threads(4)
am Ende der#pragma
? Wie diese :#pragma omp parallel private(tid) num_threads(4)
dann hast du 4 threads Ihren code.printf
mitparDF
z.B.?)Gibt es zwei Möglichkeiten, das zu erreichen, was Sie wollen:
Genau so, wie Sie sind, es zu beschreiben: jeder thread beginnt die Funktion mit dem eigenen thread id:
Den parallel-block beginnt, wie viele threads, da das system meldet, dass er unterstützt, und jeder von Ihnen führt den block. Da unterscheiden Sie sich in threadId, Sie verarbeiten unterschiedliche Daten. Um zu erzwingen, dass das starten von mehreren threads können Sie ein
numthreads(100)
oder was auch immer das pragma.Den richtigen Weg zu tun, was Sie wollen, ist ein parallel-block.
Diese Weise jeder iteration der Schleife (Wert von i) zugewiesen bekommt ein thread, der ausgeführt wird. Wie viele Iterationen werden lief parallel verfügbaren threads.
Methode 1. ist nicht sehr allgemein, und ist ineffizient, weil Sie haben so viele threads, wie du willst-Funktion aufruft. Methode 2. die kanonische (rechts -) Weg zu bekommen Ihr problem gelöst.
Sollten Sie etwas wie dieses :
Ich denke, es ist ziemlich straight forward.
numthreads
ist bereits so konfiguriert, dass 1, Sie sind einfach falsch. Meine Antwort zeigt genau die gleiche und es ist live auf Coliru, so können Sie auch überprüfen Sie diese aus Ihrem lounge-Stuhl.