Wilkening-Online Logo

C++ User-Treffen in Aachen am 14.1.2016



Von Detlef Wilkening

Wie immer am Anfang des Berichts kurz der Hinweis, dass alle Vorträge, Quelltexte, usw. - soweit vorhanden bzw. mir bekannt - auf der Vortrags-Übersichts-Seite verlinkt sind.

Das diesmalige C++ User-Treffen in Aachen fand bei NI statt. Obwohl schon Januar, hatte der Winter sich ausgerechnet diesen Tag ausgesucht um sich dann doch mal bemerkbar zu machen: es hatte tagsüber etwas geschneit - bislang hatten wir den Winter ja eher mit frühlingshaften Temperaturen erlebt. Aber ein echter C++ Programmierer läßt sich von etwas Schnee nicht abhalten, und so waren stolze 43 Leute am Abend in die Pascalstr. gekommen um den Vorträgen über C++ zu lauschen.

C++ User-Treffen Aachen 14.01.2016 - Bild 1
Foto 01: C++ User-Treffen Aachen 14.1.2016

NI hatte wieder sehr nett an uns gedacht, und ein Getränke- und Essens-Buffet aufgebaut. So konnten die, die direkt von der Arbeit kamen, etwas in den Magen bekommen - und kein Magen-Knurren störte dann die Vorträge. Wieder mal vielen Dank von hier an NI für die tolle Bewirtung und den Raum.

C++ User-Treffen Aachen 14.01.2016 - Bild 2
Foto 02: C++ User-Treffen Aachen 14.1.2016

C++ User-Treffen Aachen 14.01.2016 - Bild 3
Foto 03: C++ User-Treffen Aachen 14.1.2016

Trotz Winters war die Stimmung schon vor den Vorträgen sehr gut. Alle langten bei den Getränken und Häppchen zu, und schon im Vorfeld wurde viel über C++ und Programmieren-Allgemein geredet.

C++ User-Treffen Aachen 14.01.2016 - Bild 4
Foto 04: C++ User-Treffen Aachen 14.1.2016

Als es dann los ging zeigte sich, dass NI fast exakt kalkuliert hatte: sie hatten für genau 42 Leute Stühle aufgebaut. Aber bei noch mehr Gästen wären natürlich noch mehr Stühle vorhanden gewesen - und Raum war auch noch da.

C++ User-Treffen Aachen 14.01.2016 - Bild 5
Foto 05: C++ User-Treffen Aachen 14.1.2016

Der Vortrag began mit einer kurzen Begrüßung von NI, die Rainer Hugo vornahm.

C++ User-Treffen Aachen 14.01.2016 - Bild 6
Foto 06: Rainer Hugo bei der Begrüßung

Dann übernahm ich vorerst den Abend. Zuerst kam meine schon traditionelle Begrüßung und die Vorstellung der Themen des Abends. Der angekündigte Vortrag über die "elementaren Datentypen in C++11/14" musste leider ausfallen, da Sandra Hicks kurzfristig verhindert war. Aber aufgeschoben ist nicht aufgehoben - der Vortrag wird im März kommen. Außerdem - wie immer - machte ich einen kurzen Ausblick auf die nächsten Treffen. Und hierbei war das Wichtigste natürlich wieder die Frage nach Freiwilligen und Interessierten für weitere Vorträge und Themen für die nächsten Treffen.

Dann übernahm C++ aber den Abend: ich began mit einem kurzen Vortrag über "Parent-Shared-Ptr". Das ist im Prinzip ein ganz normaler Shared-Pointer, der einfach nur mit einem speziellen Konstruktor - dem " aliasing constructor" erzeugt wird. Dieser referenziert ein Objekt, verwaltet aber die Lebensdauer eines ganz anderen Objekts. Dieses Problem tritt typischerweise auf, wenn man ein Kind-Shared-Ptr an eine Funktion übergeben muss, dessen Lebensdauer aber am Eltern-Objekt hängt.

C++ User-Treffen Aachen 14.01.2016 - Bild 7
Foto 07: Detlef Wilkening mit "Parent-Shared-Ptr"

Witzigerweise kannten viele der Anwesenden diesen Konstruktor nicht, und gaben schon während des Vortrags zu verstehen, dass sie dieses Problem schon häufig hatten und der Aliasing-Konstruktor ihnen schon sehr geholfen hätte. So konnte ich mit meinem kleinen Vortrag echt helfen - der Shared-Pointer offenbart immer noch neue Features. Außerdem stellte ich ein Verhalten des Parent-Shared-Pointers vor, das explizit im Standard beschrieben ist - für das ich aber keine Anwendung kannte. Und hier konnte das Publikum dann mir helfen - und lieferte mir ein Beispiel-Problem hierfür - danke. Ich habe das Beispiel mittlerweile in die Präsentation eingearbeitet, die man hier als PDF herunterladen kann.

Nach meinem kleinen einfachen Vortrag übernahm Daniel Evers die Bühne - und er gestand uns seine Haßliebe zu "printf", die wohl viele von uns teilen. Auf der einen Seite hat "printf" ein einfaches kompaktes Interface, zum anderen ist "printf" nicht typsicher, nicht erweiterbar und außerdem noch langsam da der Formatierungs-String erst zur Laufzeit geparst wird.

C++ User-Treffen Aachen 14.01.2016 - Bild 8
Foto 08: Daniel Evers mit "String-Formatierungen mit TMP"

Daniel versuchte diese Probleme zu lösen, indem er "Template-Metaprogrammierung (TMP)" einsetzte, um die Formatierungen typsicher und erweiterbar schon zur Compilezeit zu bestimmen. Dazu führte er Placeholder ein, die jeweils für bestimmte Typen stehen, und die vom Compiler zur Compile-Zeit umgesetzt werden können. Mit der Definition eigener Placeholder kann diese Lösung dann auf jeden beliebigen Typ erweitert werden.

C++ User-Treffen Aachen 14.01.2016 - Bild 9
Foto 09: Ein Blick auf die "String-Formatierungen mit TMP"

Wie immer, wenn TMP im Spiel ist, war dieser Vortrag keine leichte Kost. Daniel stellte seinen Proof-of-Concept Element für Element direkt im Code vor, aber einige verloren irgendwann doch den exakten Überblick im Gewühl von Templates und Meta-Funktionen. Aber die Idee kam rüber, und die Diskussionen während des Vortrags zeigten das Interesse an einer solchen Lösung. Den Quelltext findet man hier als zip-Datei.

Daniels Vortrag war nicht so kurz und einfach wie meiner, und so waren wir alle froh über eine kleine Pause mit Getränken und anderer Stärkung. Ich nutzte die Gelegenheit und sammelte Vortrags-Vorschläge und -Angebote für die nächsten Treffen. Super, wieviele interessante und unterschiedliche Themen ich dabei als mögliche Vorträge diskutieren konnte. Ich bekam meine Zusagen für das nächste Treffen, und ich hoffe, dass die anderen Diskussionen noch Wirkung zeigen und wir all diese Themen noch als Vorträge genießen können.

C++ User-Treffen Aachen 14.01.2016 - Bild 10
Foto 10: C++ User-Treffen Aachen 14.1.2016

C++ User-Treffen Aachen 14.01.2016 - Bild 11
Foto 11: C++ User-Treffen Aachen 14.1.2016

Dann folgte der Hauptvortrag "C++ Atomics, Boost.Lookfree, Hazard-Pointer und die Thread-Hölle" von Max Neunhöffer. Max ist Mitentwickler bei der NoSQL Datenbank ArangoDB, und stellte ein Problem aus seiner Praxis vor: viele Threads wollen schnell und häufig eine globale Datenstruktur lesen, während wenige Threads nur selten und ohne große Zeitanforderungen diese Datenstruktur schreiben wollen. Problem: wie löst man dies sicher und vor allem mit guter Performance?

C++ User-Treffen Aachen 14.01.2016 - Bild 12
Foto 12: Max Neunhöffer mit "C++ Atomics, Boost.Lookfree, Hazard-Pointer und die Thread-Hölle"

Zuerst zeigte uns Max "ungeschützten Verkehr", daher eine einfache ungesicherte Lösung die aber Race-Conditions erzeugt. Wichtig war Max hier vor allem die Performance-Messung, die die theoretisch mögliche Obergrenze bei "gesichertem Verkehr" darstellt. Jeder Art von Sicherung verursacht Aufwand - die "ungeschützte" Lösung kann also nicht übertroffen werden.

Danach stellt Max eine Lösung vor, die ganz normal die Zugriffe mit Locks synchronisiert, und maß wieder die Performance. Diese Lösung war weitaus langsamer, und skalierte vor allem bei vielen lesen Threads überhaupt nicht gut - sondern wurde dann sogar wieder langsamer.

Nach dieser Motivation stellte Max die "Hazard-Pointer" vor. Sie sind eine seit 2004 bekannte Lösung für dieses Problem, die vor allem ohne Locks auskommen.

C++ User-Treffen Aachen 14.01.2016 - Bild 13
Foto 13: Ein Blick auf die Idee der Hazard-Pointer

Problematischer als die Idee selber war dann die Umsetzung - vor allem in einer wiederverwendbaren Klasse mit einfachem Interface. Dies ist laut Max mit den Original-Hazard-Pointern nur schwer bzw. nicht umzusetzen. Darum haben sich die ArangoDB-Entwickler etwas eigenes ausgedacht, das auf der Idee der Hazard-Pointer basiert, aber in einer Klasse kapselbar war: der "DataProtector".

C++ User-Treffen Aachen 14.01.2016 - Bild 14
Foto 14: Max Neunhöffer mit "C++ Atomics, Boost.Lookfree, Hazard-Pointer und die Thread-Hölle"

Max stellte danach im Detail den Code im "DataProtector" vor, bewies die MT-Korrektheit der Lösung und zeigte zum Schluß seine Performance-Messungen. Natürlich war auch diese Lösung nicht so schnell wie der "ungeschützte Verkehr", war aber performanter als die Lock-Lösung und skalierte weitaus besser. Den Vortrag findet man hier als PDF.

Schon während des Vortrags gab es rege Diskussionen und auch einige Verbesserungs-Vorschläge für den Code. Und auch nach dem Vortrag wurde noch lange weiter diskutiert - und Max versprach allen Tipps und Hinweisen nachzugehen. Mittlerweile habe ich von Max eine erste Antwort bekommen: Der "ungeschützte Verkehr" Test tut wirklich, was man von ihm erwartet - Max hat sich den Assemblercode angeschaut - gebaut mit G++ 5.2 und -O3. Außerdem hat Daniel Frey eine Änderung am Data-Protector vorgenommen, indem er einen "std::shared_ptr mit atomic_load/_store" und eine Thread-Barrier mit "_consume" einsetzte. Zumindest seinen Messungen nach ist diese Lösung noch performanter. Wir warten mal ab, was Max dazu sagt. Auf jeden Fall hat Daniel angeboten, seine Änderungen bei einem der nächsten Treffen in einem Lightning-Vortrag vorzustellen - das lassen wir uns natürlich nicht entgehen.



Den nächsten Termin, weitere Berichte und andere Informationen zu den C++ User-Treffen in Aachen finden sich auf meiner "C++ User-Treffen in Aachen" Seite.

C++ User-Treffen: