2017-01-30 2 views
4

Bevor ich die Frage ausführlicher erläutere, werde ich feststellen, dass die Antwort offensichtlich implementierungsabhängig ist, also frage ich in erster Linie nach libstdC++, würde mich aber auch über libC++ informieren. Das Betriebssystem ist Linux.Ist std :: future spin-wait?

Aufruf wait() oder get() auf einem std::future blockiert, bis das Ergebnis von einem asynchronen Betrieb gesetzt ist - entweder eine std::promise, std::packaged_task oder std::asyn Funktion. Die Verfügbarkeit des Ergebnisses wird über einen gemeinsamen Status mitgeteilt, der im Grunde eine atomare Variable ist: Der future wartet darauf, dass der gemeinsam genutzte Status vom Versprechen (oder asynchronen Task) als bereit markiert wird. Dieses Warten und Benachrichtigen wird in libstdC++ über einen Systemaufruf futex implementiert. Zugegeben, dass Futexs hochperformant sind, in Situationen, in denen eine Zukunft nur eine extrem kurze Zeit (in der Größenordnung von Mikrosekunden) erwartet, würde es scheinen, dass ein Leistungsgewinn durch kurzzeitiges Drehen im gemeinsamen Zustand erreicht werden könnte bevor Sie auf den Futex warten.

ich keine Beweise für eine solche Spinnen in der aktuellen Implementierung gefunden haben, aber ich einen Kommentar in atomic_futex.h at line 161 gefunden, wo ich erwartet, wie Spinnen zu finden wäre:

eher die folgenden
// TODO Spin-wait first. 

So ist meine Frage : Gibt es wirklich Pläne, ein Spin-Wait zu implementieren, und wenn ja, wie wird die Dauer entschieden? Gibt es darüber hinaus die Art von Funktionalität, die eventuell durch eine zukünftige Richtlinie spezifiziert werden könnte?

+0

Es ist ein Implementierungsdetail. Es könnte eine kleine Warteoptimierung sein, um auf einige Versuche zu warten, und dann tatsächlich warten (von der CPU genommen werden) – AndyG

+0

Ich denke, es ist unter Linux nicht relevant, da der Mutex Systemaufruf unter Linux eigentlich ein Futex ist . – SergeyA

+0

@SergeyA Dennoch kann ein Futex-Aufruf mehrere Mikros dauern, während das Spinnen nur einige Nanos sein kann. Mir ist klar, dass es sich um eine Optimierung für einen sehr speziellen Anwendungsfall handelt. –

Antwort

3

Ich werde die Frage beantworten: Führt std::future::get() eine Dreh-warten?

Die Antwort für alle von C++ ist: Es ist ein Implementierungsdetail. Eine konforme Standardbibliothek könnte sich drehen oder nicht (im gleichen Sinne kann std::mutex::lock() rotieren). Wird es einen Mechanismus geben, um festzulegen, ob und wie in Zukunft gedreht werden soll? Die Orte zu sehen sind in std::experimental::future (kommt bald zu einer Vollversion der Standard-Bibliothek), boost::future (Prüfungsgrund für, was später in den Standard gehen könnte), und hpx::future (leistungsorientierte Bibliothek mit erweiterten Funktionen für future Management). Keiner von diesen hat Mechanismen zur expliziten Spezifikation von Spinnereien, und es gab auch keine Besprechung in den mir bekannten Sitzungsprotokollen oder auf der ISO-CPP-Mailingliste. Es ist sicher zu sagen, dass so etwas wie eine get_with_spins Funktion nicht in der Pipeline ist.

Zu antworten für libstdc++ (und libc++): Sie drehen sich auch nicht. Abgesehen von der TODO, die von the original patch kam, sieht es nicht so aus, als ob es irgendeinen Plan gibt, dies zu ändern. Ich habe die GCC-Mailingliste nach Erwähnungen zur Änderung dieses Verhaltens durchsucht, aber keine gefunden. Ein Spin-Pre-Sleep kann im allgemeinen Fall schaden (wenn keiner der get() s einen Wert hat, haben Sie eine Menge CPU-Zyklen verschwendet), so dass eine Änderung hier negative Auswirkungen haben könnte.

Zusammengefasst: Implementierungen scheinen sich jetzt nicht zu drehen und es scheint keine Pläne zu geben, das Verhalten in naher Zukunft zu ändern, aber das kann sich jederzeit ändern.

Verwandte Themen