c ++ warum std :: async langsamer als sequenzielle Ausführung

8
%Vor%

Hallo,

Also oben sind zwei Funktionen zum Aufsummieren eines Vektors von Zufallszahlen.

Ich habe mehrere Läufe gemacht, aber es scheint, dass ich nicht von std::async profitiert habe. Unten sind einige Ergebnisse, die ich bekommen habe.

%Vor%

In allen vier Fällen verbrachte die asynchrone Version mehr Zeit. Aber im Idealfall hätte ich zweimal schneller sein sollen, oder?

Habe ich etwas in meinem Code übersehen?

Nebenbei laufe ich auf OS X 10.10.4 Macbook Air mit 1.4 GHz Intel Core i5 .

Danke,

Bearbeitungen:

  1. Compiler-Flags: g++ -o asum asum.cpp -std=c++11
  2. Ich habe das Flag so geändert, dass -O3 und die Vektorgröße 10000000 enthält, aber die Ergebnisse sind immer noch verworren.
%Vor%
Ling 08.11.2017, 15:35
quelle

3 Antworten

6

hier

%Vor%

async speichert seine eigene Vektorkopie zweimal. Sie sollten std::cref verwenden und sicherstellen, dass die Futures abgerufen werden, bevor der Vektor stirbt (wie in Ihrem aktuellen Code) und dass die Zugriffe ordnungsgemäß synchronisiert werden (wie in Ihrem aktuellen Code).

Wie in den Kommentaren erwähnt, kann der Thread-Erstellungsaufwand den Code weiter verlangsamen.

    
Massimiliano Janes 08.11.2017, 15:55
quelle
1

Erstens ist die Leistung Ihrer ursprünglichen asynchronen Funktion im Vergleich zur sequenziellen Funktion schlecht, weil sie eine weitere Kopie Ihrer Testdaten erstellt, wie in anderen Antworten erwähnt. Zweitens können Sie die Verbesserung nach dem Behoben des Kopierproblems möglicherweise nicht sehen, da das Erstellen von Threads nicht billig ist und Ihren Leistungszuwachs beeinträchtigen kann.

Aus den Benchmark-Ergebnissen kann ich sehen, dass die asynchrone Version 1,88-mal schneller ist als die der sequenziellen Version für N = 1000000. Wenn ich jedoch N = 10000 verwende, ist die asynchrone Version 3,55 mal langsamer. Sowohl Nicht-Iterator- als auch Iterator-Lösungen führen zu ähnlichen Ergebnissen.

Außerdem sollten Sie beim Schreiben Ihres Codes Iterator verwenden, da dieser Ansatz flexibler ist. Sie können beispielsweise verschiedene Containertypen ausprobieren, erhalten eine ähnliche Leistung im Vergleich zur C-Style-Version und sind auch eleganter IMHO:) / p>

Benchmark-Ergebnisse:

%Vor%

Komplette Codebeispiel

%Vor%     
hungptit 10.11.2017 05:45
quelle
0

Nun, dies ist das einfachste mögliche Beispiel und die Ergebnisse sollten aus folgenden Gründen nicht bindend sein.

  1. Wenn Sie einen Thread erstellen, dauert es einige zusätzliche CPU-Zyklen, um den Threadkontext und -stapel zu erstellen. Diese Zyklen werden zur Summenfunktion hinzugefügt.

  2. Wenn der Hauptthread diesen Code ausführt, war der Hauptthread leer und hat nichts anderes als die Summe

  3. ausgeführt

Wir gehen für Multithreading-Lösung nur dann, wenn wir etwas in einem einzelnen Thread nicht erreichen können oder wir müssen synchron auf einige Eingaben warten.

Indem Sie nur Threads erstellen, erhöhen Sie nicht die Leistung. Sie erhöhen die Leistung, indem Sie Multithread-Anwendungen, bei denen Sie leere CPUs verwenden können, sorgfältig entwerfen, wenn einige andere Dinge auf IO warten.

    
Daksh Gupta 08.11.2017 15:51
quelle