Introduction à la programmation lock-free en C++11 au moyen des atomics. Présentation données par Cyril Comparon lors des rencontres C++ de Montpellier (novembre 2014).
Introduction au lock-free programming avec std::atomics
1. Introduction au
lock-free programming
avec std::atomics
Meetup C++
25 novembre 2014
Montpellier
Cyril Comparon
2. Multi-tasking
Concurrence
Le système est composé de plusieurs tâches s’exécutant de manière (partiellement)
indépendante.
Parallélisme
Ces tâches peuvent en plus s’exécuter au même moment.
Cyril Comparon – Meetup C++ Montpellier 25/11/2014
3. Multi-tasking
Multi-threading
Les différentes tâches sont des exécutions distinctes du même programme, partageant le même
espace mémoire.
thread1 thread2
Cyril Comparon – Meetup C++ Montpellier 25/11/2014
4. Multi-tasking
Multi-threading
Les différentes tâches sont des exécutions distinctes du même programme, partageant le même
espace mémoire.
thread1 thread2
Cyril Comparon – Meetup C++ Montpellier 25/11/2014
5. Multi-tasking
Thread-safety
Une structure de donnée partagée est thread-safe si elle garantit un fonctionnement prédictible
et reste dans un état valide (non corrompu) quel que soit l’ordre d’appel de ses méthodes.
Plusieurs implémentations possibles:
- Re-entrancy, thread-local storage, immutable objects outils/work-arounds
- Mutual exclusion
- Atomic operations
Cyril Comparon – Meetup C++ Montpellier 25/11/2014
8. principales opérations atomiques de std::atomics
En C++11, principalement trois opérations atomiques ont été standardisées, car le plus souvent
supportées par le hardware :
int exchange(int desired)
Cyril Comparon – Meetup C++ Montpellier 25/11/2014
Atomically replaces the underlying value with desired.
The operation is read-modify-write operation.
bool compare_exchange(int &expected,
int desired)
a.k.a CAS
Atomically compares the value stored in *this with the
value pointed to by expected, and if those are equal,
replaces the former with desired (performs read-modify-
write operation). Otherwise, loads the actual
value stored in *this into *expected (performs load
operation).
int fetch_add(int incr)
Atomically replaces the current value with the result of
arithmetic addition of the value and incr. The operation
is read-modify-write operation.
14. Questions en vrac
Pourquoi tu me dis que c’est compliqué alors que ça a l’air tout simple ?
Pourquoi je n’envoie pas tout sur mon GPU qui est vachement plus puissant que mon CPU et il
paraît que tout le monde fait que ça maintenant ?
Pourquoi on s’embête avec tout ça alors qu’il existe des langages et des outils de plus haut
niveau qui me cachent toute la complexité ?
Y a-t-il des application pratiques intéressantes ?
Est-ce spécifique au C++ ?
Autres questions ?
Cyril Comparon – Meetup C++ Montpellier 25/11/2014
15. Les prochaines fois
- Bas niveau :
• Pourquoi ça ne devrait pas marcher ?
Weak cache coherency, out-of-order execution
• Pourquoi ça marche quand même ?
Memory ordering / memory barriers
- Le C++11 memory model
- Penser en termes de transactions (ACID)
- Algorithmes lock-free un peu plus intéressants
- Différents niveaux de lock-freedom
- Le problème ABA
Cyril Comparon – Meetup C++ Montpellier 25/11/2014
16. Remerciements
CppReference
http://en.cppreference.com/w/cpp/atomic
Herb Sutter – atomic<> Weapons (2012)
http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2
Herb Sutter – Lock-Free Programming
http://channel9.msdn.com/Events/CPP/C-PP-Con-2014/Lock-Free-Programming-or-Juggling-Razor-Blades-Part-I
The Concurrency Kit
http://concurrencykit.org
Wikipedia
http://en.wikipedia.org
Cyril Comparon – Meetup C++ Montpellier 25/11/2014
17. Remerciements
CppReference
http://en.cppreference.com/w/cpp/atomic
Herb Sutter – atomic<> Weapons (2012)
http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2
Herb Sutter – Lock-Free Programming
http://channel9.msdn.com/Events/CPP/C-PP-Con-2014/Lock-Free-Programming-or-Juggling-Razor-Blades-Part-I
The Concurrency Kit
http://concurrencykit.org
Wikipedia
http://en.wikipedia.org
Cyril Comparon – Meetup C++ Montpellier 25/11/2014
Editor's Notes
Me présenter
Piqûre de rappel – multi-tasking - système concurrent - parallélisme
Vieux mono-CPU – scheduler de l’OS – (preemptive multitasking) illusion de parallélisme – multithreading déjà très utilisé
Parallélisme induit par le multi-CPU
Multithreading rendu encore plus important à cause de cela
Patterns proposés par wikipedia
Lock-based = critical sections = blocking algos
Lock-free = non-blocking algos
Que va-t-il se passer et pourquoi ?
Race condition ! Dépend de la température de la pièce !
Ca marche ! Mais performances bof et surtout, que se passe-t-il si l’opération n’est pas triviale, fait des I/O ou a d’autres dépendances ?
On peut le simuler en suspendant un thread.
Ca marche ! Mais performances bof et surtout, que se passe-t-il si l’opération n’est pas triviale, fait des I/O ou a d’autres dépendances ?
On peut le simuler en suspendant un thread.
Obstruction-free ! = même en suspendant un des deux threads, l’autre thread finit son boulot !
(c’est une des propriétés des algorithmes lock-free)
Obstruction-free ! = même en suspendant un des deux threads, l’autre thread finit son boulot !
(c’est une des propriétés des algorithmes lock-free)
std::atomic<T>::is_lock_free() renseigne si T est supporté sans lock sur le hardware cible.
Sur les machines les plus courantes, les entiers 32 et 64 bits et les pointeurs.
Parce que le compilateur et le processeur et ses caches ont leurs raisons
N’adresse pas le même genre de problème – embarrassingly parallel problems
Parce que ça ne fait pas de mal de le savoir quand même, et parce que si déjà on fait du C++, c’est qu’on est un peu maso et qu’on cherche à tirer le max de perf/watt.
De toute façon les techniques que vous allez apprendre et notamment la pensée « transactionnelle » est précieuse dans les environnements distribués bien au-delà du multithreading !
Oui, beaucoup, c’est un domaine très actif de la recherche. Plus prosaïquement, ce sont les briques de base sans lesquelles vous n’auriez meme pas vos mutexes.
Non, il y a meme une API dédiée dans la lib java, c’est dire !