10.02.2013 Aufrufe

Untitled

Untitled

Untitled

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

}<br />

}<br />

3.1 Parallelität auf Schleifenebene 33<br />

for(unsigned int i = 0; i < x.size(); ++i<br />

)<br />

{<br />

y[i] += a * x[i];<br />

}<br />

Der Effekt ist nicht der beabsichtigte: Statt dass sich<br />

die Threads im Team die Arbeit untereinander aufteilten,<br />

führt jeder der Threads die gesamte Berechnung aus! Bei<br />

n Threads wird die ganze Schleife also unnötigerweise nmal<br />

ausgeführt. Im besten Fall wird n-mal a ∗ x[i] zu y[i]<br />

addiert. Hinzu kommen mögliche unbeabsichtige Seiteneffekte,<br />

da die Threads unsynchronisiert auf die gemeinsam<br />

genutzten Vektoren zugreifen und es so zu einer Wettlaufsituation<br />

(engl. Race Condition) kommen kann (siehe hierzu<br />

auch Kapitel 1.2.1). Dies ist z. B. dann der Fall, wenn zwei<br />

parallele Threads den gleichen Wert für die Schleifenvariable<br />

i zur Zeit bearbeiten, den Wert von y[i] jeweils gelesen<br />

haben und davor stehen, den neuen Wert von y[i] zu schreiben.<br />

Beide Threads arbeiten in diesem Fall mit dem alten<br />

Wert von y[i]. Die Änderung durch den Thread, der zuerst<br />

seinen neuen, um a ∗ x[i] erhöhten Wert nach y[i] schreibt,<br />

wird durch den nachfolgenden Thread überschrieben. Die<br />

Änderung von y[i] durch den ersten Thread geht also verloren.<br />

Vielmehr benötigt man für dieses Programm das Arbeit<br />

aufteilende Pragma #pragma omp for, um dem Compiler<br />

mitzuteilen, die Schleifendurchläufe auf mehrere Threads<br />

innerhalb des Teams, das den parallelen Abschnitt ausführt,<br />

aufzuteilen, wie in Listing 3.3 gezeigt.

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!