CppCon 2014: Herb Sutter "Lock-Free Programming (or, Juggling Razor Blades), Part I"

CppCon · 118K views · 2014 · 1:00:24

Open on YouTube

C, C++, Rust, Go & systems languagesSoftware performance & optimizationtalk

Why Stack Overflow recommends it

Stack Overflow users link it when answering questions about std::atomic, memory ordering, double-checked locking and lock-free queues, as the go-to explanation of how to use atomics correctly.

Recommended by 10 people across 16 different months, 2014 to 2025.

What it is

A one-hour CppCon 2014 talk by Herb Sutter, chair of the ISO C++ committee, on designing and writing lock-free algorithms and data structures with C++ std::atomic. It is example-driven and distinct from his 'atomic Weapons' talk, which covered the memory model itself.

What people said

Strong rec Zulan · 2017-03 · Stack Overflow · on “consuming linkedlist queue in multithreads”

First and foremost, you can never prove multi-threaded code to be correct through testing . Your hunch, that you need a lock / critical section is correct. Your test is particularly easy on the queue. The following breaks your queue quickly: for (int i = 0; i < 10000; ++i) { queue.add(i); } double timer_started = omp_get_wtime(); #pragma omp parallel { size_t counter = 0; Node *n; while ((n = queue.remove()) != NULL) { processNode(n); counter++; } #pragma omp critical std::cout << "Thread " << omp_get_thread_num() << " processed " << counter << " nodes." << std::endl; } void processNode(Node *node) {} Show for example the following interesting result: Thread 1 processed 11133 nodes. Thread 0

Strong rec Yuri Beard · 2020-04 · Stack Overflow · on “Why does this `std::atomic_thread_fence` work”

It sounds like that the x86 implementation of the atomic STORE/LOAD operations takes advantage of the strongly-ordered asm memory model of the x86 architecture [LINK] . See also C/C++11 mappings to processors [LINK] The situation is very different on ARM, which the code snippet in the question demonstrates. Herb Sutter made a great presentation on this for CPPCON 2014: [this video]

Recommends qqibrow · 2015-01 · Stack Overflow · on “how to handle cached data structures with multi-threading (e.g. openmp)”

A efficient singleton is the best choice for you. Please check here. efficient thread-safe singleton in C++ [LINK] Also, Herb Sutter talks about that in CppCon 2014 [this video] Here is the full code snippet from the video I showed above: class Foo { public: static Foo* Instance(); private: Foo() {init();} void init() { cout << "init done." << endl;} // your init cache function. static atomic<Foo*> pinstance; static mutex m_; }; atomic<Foo*> Foo::pinstance { nullptr }; std::mutex Foo::m_; Foo* Foo::Instance() { if(pinstance == nullptr) { lock_guard<mutex> lock(m_); if(pinstance == nullptr) { pinstance = new Foo(); } } return pinstance; } run the code here: [LINK]

Recommends engf-010 · 2015-02 · Stack Overflow · on “Is there a way of making atomic shared_ptr in libstd++?”

There is an interesting part about atomic shared pointers somewhere in this video series (note there are 2 videos) by Her Sutter ! [this video] en [LINK]

Recommends anorm · 2015-09 · Stack Overflow · on “Could optimization break thread safety?”

Compiler optimization can not break thread safety! You might however experience issues with optimizations in code that appeared to be thread safe but really only worked because of pure luck. If you access data from multiple threads, you must either Protect the appropriate sections using std::mutex or the like. or, use std::atomic . If not, the compiler might do optimizations that is next to impossible to expect. I recommend watching CppCon 2014: Herb Sutter "Lock-Free Programming (or, Juggling Razor Blades), Part I" [this video] and Part II [LINK]

Recommends Tamas Ionut · 2016-05 · Stack Overflow · on “Compare and swap with and without garbage collector”

Ok, so CAS is an atomic instruction, that is there is special hardware support for it. Its main use is to not use locks at all when implementing your data structures and other operations, since using locks, if a thread takes a page fault, a cache miss or is being descheduled by the OS for instance the thread takes the lock with it and all the rest of the threads are blocked. This obviously yields serious performance issues. CAS is the core of lock-free programming [LINK] and here [LINK] and here [this video] . CAS basically is the following: CAS(CURRENT_VALUE, OLD_VALUE, NEW_VALUE) <=> if CURRENT_VALUE==OLD_VALUE then CURRENT_VALUE = NEW_VALUE You have a variable (e.g. class variable) and you hav

Recommends Zulan · 2017-05 · Stack Overflow · on “Parallelizing a Breadth-First Search”

**Yes**. It is absolutely necessary to protect all access to `q` in this case as `std::queue` is not a concurrent data structure. Take a look at this talk [this video] to get a glimpse of the things that you need to think about when considering concurrent data structures.

Recommends Richard Hodges · 2017-08 · Stack Overflow · on “mix atomic and non atomic variables and caches”

It looks fine to me. I would encourage you to watch the lecture called "atomic weapons". It all made sense to me after that. [this video]

Recommends Marek R · 2022-03 · Stack Overflow · on “C++ multithreading locking a mutex before assigning to an atomic”

`In C++ do you need to lock a mutex before assigning to an atomic?` NO! Please check out this C++ standard comity member talk: "Lock-Free Programming (or, Juggling Razor Blades)" [this video] .

Recommends Jonathan S. · 2023-02 · Stack Overflow · on “Does the context switch retain (keep state of variables) the value of the variables when it resumes the task?”

@Coder23 You could of course read the variable twice, but you'll still have a window for a race condition to occur - it would just have to happen between the second read and the write. No matter how often you read the variable, if you don't have proper synchronization, there will always be a race window. I'd recommend you to watch this presentation (both parts): [this video]