C ++ 0x Threads geben keine Beschleunigung

8

Ich habe ein Programm geschrieben für die Suche nach dem Maximum in Arrays mit C ++ 0x Threads (zu Lernzwecken). Für die Implementierung habe ich standard thread und future Klassen verwendet. Die parallelisierte Funktion zeigt jedoch immer dieselbe oder schlechtere Laufzeit als nicht parallelisiert.

Code ist unten. Ich habe versucht, Daten in einem eindimensionalen Array, mehrdimensionalen Array zu speichern und endete mit mehreren Arrays. Allerdings hat keine Option gute Ergebnisse erzielt. Ich habe versucht, meinen Code aus Eclipse und der Befehlszeile zu kompilieren und auszuführen, jedoch ohne Erfolg. Ich habe auch einen ähnlichen Test ohne Array-Nutzung versucht. Die Parallelisierung gab dort nur 20% Geschwindigkeit. Aus meiner Sicht führe ich sehr einfaches paralleles Programm, ohne Sperren und fast keine gemeinsame Nutzung von Ressourcen (jeder Thread arbeitet auf seinem eigenen Array). Was ist ein Flaschenhals?

Mein Rechner hat einen Intel Core i7 Prozessor mit 2,2 GHz und 8 GB RAM, auf dem Ubuntu 12.04 läuft.

%Vor%

Timing hat gezeigt, dass fast die gesamte Zeit in find_max_parralel von

verbraucht wird %Vor%

Befehlszeile für die Kompilierung

%Vor%

Update. Das Problem ist gelöst. Ich habe die gewünschten Ergebnisse mit demselben Test erhalten. 4 Threads ergeben ca. 3.3 Speed ​​Up, 3 Threads geben ca. 2.5 Speed ​​Up, 2 Threads verhalten sich nahezu ideal mit 1.9 Speed ​​Ups. Ich habe gerade System mit einigen neuen Updates neugestartet. Ich habe keinen signifikanten Unterschied in CPU-Auslastung und laufenden Porgrammen gesehen.

Danke an alle für die Hilfe.

    
Andrii 30.11.2012, 15:16
quelle

2 Antworten

14

Sie müssen std::launch::async explizit angeben.

%Vor%

Wenn Sie das Flag std::launch::async | std::launch::deferred auslassen, wird angenommen, was es der Implementierung überlässt, ob die Task asynchron oder verzögert gestartet werden soll.

Aktuelle Versionen von gcc verwenden std::launch::deferred , MSVC hat einen Laufzeit-Scheduler, der über die Laufzeit entscheidet, wie die Aufgabe ausgeführt werden soll.

Beachten Sie auch, wenn Sie versuchen möchten:

%Vor%

Dies wird auch blockiert, weil der Destruktor von std::future auf den Abschluss der Aufgabe wartet.

    
inf 30.11.2012, 15:17
quelle
3

Ich habe gerade den gleichen Test mit gcc-4.7.1 ausgeführt und die threaded-Version ist ungefähr viermal schneller (auf dem 4-Core-Server). Das Problem liegt also offensichtlich nicht in der Implementierung von std :: future, sondern in der Auswahl von Threading-Einstellungen, die für Ihre Umgebung nicht optimal sind. Wie oben erwähnt wurde, ist der Test nicht CPU, sondern speicherintensiv. Der Flaschenhals ist definitiv Speicherzugriff. Sie sollten wahrscheinlich einen CPU-intensiven Test (wie die Berechnung der PI-Nummer mit hoher Genauigkeit) durchführen, um das Threading richtig zu bewerten.

Ohne mit einer unterschiedlichen Anzahl von Threads und unterschiedlichen Array-Größen zu experimentieren, ist es schwer zu sagen, wo genau der Engpass liegt, aber es gibt wahrscheinlich nur wenige Dinge im Spiel:  - Sie haben wahrscheinlich 2-Kanal-Speicher-Controller (es ist entweder 2 oder 3), so führt über 2 Threads nur zusätzliche Konkurrenz um Speicherzugriff. Daher ist Ihre These, dass es keine Sperrung und keine gemeinsame Nutzung von Ressourcen gibt, nicht korrekt: Auf der Hardwareebene gibt es Konflikte um den gleichzeitigen Speicherzugriff.  - Nichtparallele Version wird effizient optimiert, indem Daten vorab in den Cache abgerufen werden. Auf der anderen Seite gibt es die Chance, dass Sie in der parallelen Version mit einem intensiven Kontextwechsel und als Ergebnis des CPU-Caches fertig werden.

Für beide Faktoren ist eine Beschleunigung wahrscheinlich, wenn Sie die Anzahl der Threads auf 2 reduzieren.

    
Daniel Neiter 01.12.2012 01:53
quelle