2016-11-23 3 views
1

Ich habe ein Problem, wobei ich ein paralleles System gegen ein nicht-paralleles System testen möchten.Establishing Speicher in Parallel C++

im System 1 I stellen die Speicher als solcher:

std::vector<double>* p_val_vec_main = new std::vector<double>(*mpStages); 
std::vector<double>* p_val_vec_slave = new std::vector<double>(*mpStages-1); 
std::vector<std::vector<double> >* p_mat_cache = 
    new std::vector<std::vector<double> >(3, std::vector<double>()); 

Diese Vektoren werden um geleitet und in einem RAII System verwendet, das wiederholt wird, damit die Zeiger und neue Syntax.

Im System 2 (das Parallelsystem), ich versuche, die 3 Vektoren parallel dort gegebenen aufzubauen ist nicht - vermutet - als solche Überlappung:

#pragma omp parallel 
{ 
    std::vector<double>* p_val_vec_main = new std::vector<double>(*mpStages); 
    std::vector<double>* p_val_vec_slave = new std::vector<double>(*mpStages-1); 
    std::vector<std::vector<double> >* p_mat_cache = 
    new std::vector<std::vector<double> >(3, std::vector<double>()); 
} 

jedoch das erste Mal, wenn ich zu referenzieren ‚p_val_vec_main‘ außerhalb des Pragma Block, aber in der Methode, wo der Pragma-Block ist, auf ein gültiges Element in System 2 ich erhalte den Fehlercode:

error: 'p_val_vec_main' was not declared in this scope 

mich gefragt, ob jemand wusste, warum dies geschah? Meine einzigen Gedanken darüber, was das sein könnte, wären möglicherweise lokale/globale Zusammenstöße.

+0

Wenn Sie Sie „Referenz p_val_vec_main“ auf System sagen 2, tun Sie meinen Sie buchstäblich auf die Variable verweisen Sie in Ihrem 'Pragma omp parallel' Block deklariert? Oder sagen Sie, dass Sie sich auf eine Kopie dieses Zeigers beziehen, der in Ihrem RAII-System "herumgereicht" wurde? – Edward

+0

Außerhalb des Pragma-Blocks, aber in der Methode, wo der Pragma-Block ist @Edward – mwtmurphy

+0

'neue std :: vector <...' ist fast immer eine schlechte Idee. Das gilt für alle Container. Verwenden Sie einfach den Containertyp direkt."Verwenden von RAII" ist kein Argument _for_ pointer, es ist ein Argument _against_ pointers. – MSalters

Antwort

0

Compiler Fehler beschreibt das Problem offenbar. p_val_vec_main im Block erklärt:

#pragma omp parallel 
{ 
    std::vector<double>* p_val_vec_main = new std::vector<double>(*mpStages); 
    // Other declarations skipped 
} 

Sie es nicht aus diesem Block zugreifen können. Lesen Sie mehr über Block scope here.

+0

Ich verstehe Bereiche, aber meine Frage ist, warum es dies für einen parallelen Bereich tut. Zusätzlich warum sollte es die anderen Erklärungen überspringen? – mwtmurphy

+0

@ Murphy'sLaw '#pragma omp parallel 'definiert eine Region, die parallel ausgeführt werden soll. Dieser Bereich hat dieselben Sichtbarkeitsregeln wie andere Blockbereiche. Wenn also Ihre andere Logik außerhalb dieses Bereichs liegt, kann sie nicht auf die dort definierten Variablen zugreifen. – Nikita

+0

@ Murphy'sLaw War das hilfreich oder brauchst du mehr Hilfe? Wenn diese oder eine andere Antwort Ihre Frage gelöst hat, ziehen Sie bitte eine positive Bewertung und/oder [akzeptieren] in Betracht (http://meta.stackexchange.com/q/5234/179419), indem Sie auf das Häkchen klicken. – Nikita

1

Das Problem, das Sie haben, ist, dass der #pragma omp parallel-Block, den Sie nur auf System 2 verwenden, eine zusätzliche Bereichsebene (zwischen den öffnenden und schließenden geschweiften Klammern) erstellt, die die Zeigervariable p_val_vec_main (und die anderen Variablen) verbirgt irgendwelche Aussagen davor und danach. Dies ist ein notwendiger Teil der Verwendung von omp parallel, da OpenMP intern die Anweisungen innerhalb eines parallel Blocks in eine Funktion konvertiert, so dass alle Variablen, die innerhalb dieses Blocks deklariert sind, funktionslokal werden.

Wenn Sie die Vektoren innerhalb eines omp parallel Block initialisieren wollen, aber sie außerhalb davon verwenden, werden Sie die Zeiger auf einem höheren Niveau Umfang erklären müssen, wie folgt aus:

std::vector<double>* p_val_vec_main; 
std::vector<double>* p_val_vec_slave; 
std::vector<std::vector<double> >* p_mat_cache; 
#pragma omp parallel 
{ 
    p_val_vec_main = new std::vector<double>(*mpStages); 
    p_val_vec_slave = new std::vector<double>(*mpStages-1); 
    p_mat_cache = 
    new std::vector<std::vector<double> >(3, std::vector<double>()); 
} 
//p_val_vec_main can be used here 
0

Gefunden eine technische Antwort online:

Intern implementiert GCC dies, indem er eine Funktion erstellt und den zugehörigen Code in diese Funktion verschiebt, so dass alle in diesem Block deklarierten Variablen zu lokalen Variablen dieser Funktion werden (und somit Locals zu jedem Thread).

ICC dagegen verwendet einen Mechanismus, der fork() ähnelt und keine magische Funktion erzeugt.

Beide Ausführungen sind natürlich, gültig und semantisch identisch.

von Genommen: http://bisqwit.iki.fi/story/howto/openmp/#ExampleInitializingATableInParallelMultipleThreads