Memory Model
C++11 – C++23
About Me:
[email protected]
www.linkedin.com/in/alexdathskovsky
https://www.cppnext.com
Important Question
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Does the processor executes the
program as you wrote it?
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
The Answer
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Short Version
• Usually Not
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Longer Version
• It will run what you have intended but:
• Compilers reorder and change
operations
• CPU’s use threading and OOO
execution
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Compiler Optimisations
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
If you were the compiler, what would you do?
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
If you were the compiler, what would you do?
• Compiler detects that get_pivot yields the
same value
• It's better to call get_pivot once and call the
value from register again and again
• data[p] has the same value, it will be stored
in a register
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Compiler can do even better
• Modern (X86) CPUs have vectorization
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Compiler can do even better
• If everything can be know in compile time
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Algebraic Simplifications
(v + 1) + 3 ->
v + (1+3) ->
v+4
Strength Reduction
Loop unrolling
• Compiler may unroll your loops
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Loop unrolling
• Compiler may unroll your loops
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Dead Code Removal
• If there is unnecessary code, it will probably
be removed
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Dead Code Removal
• If there is unnecessary code, it will probably
be removed
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
inlining
• inlines function calls
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
inlining
• inlines function calls
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
inlining recursion
• Tail recursion can be inlined
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
inlining recursion
• Tail recursion can be inlined
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
CPU Optimisations
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
INO Execution
Source: https://en.wikipedia.org/wiki/Central_processing_unit
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
INO Execution
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
INO Execution
• instruction fetch
• if operands available execute it if not fetch them
• The instruction is executed by the functional unit
• The functional unit writers the result back to the
register or memory
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
INO vs OOO Execution
Source::
https://www.semanticscholar.org/paper/RISC-V-Reward:-Building-Out-of-Order-Processo
rs-in-Zekany-Tan/f7f6d27f334604c3c85f0b8d21d2a9b4df22a983
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
OOO Execution
From F. Yazdanpanah, C.
Alvarez-Martinez, D.
Jimenez-Gonzalez and Y. Etsion,
"Hybrid Dataflow/von-Neumann
Architectures," in IEEE
Transactions on Parallel and
Distributed Systems
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
OOO Execution : Dynamic Scheduling
• instruction fetched
• instruction dispatched to instruction queue
• the instruction waits in the queue untils its input
operand are available
• if operands available instruction is allowed to
leave the queue before other instructions
• the instruction is issued to a functional unit
• only if all older instructions have completed the
operation the result is written to register file
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Dynamic Scheduling
• Check for structural hazards
• an instruction can be issued if a functional unit
is available
• an instruction stalls if no appropriate
functional unit available
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Dynamic Scheduling
• Check for data hazards
• an instruction can be executed when its
operands have been calculated or loaded
from memory
• an instruction stalls if operands are not
available
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Dynamic Scheduling
• instruction can be executed out of order if there
is no dependency on previous instructions
• ready instructions can execute before earlier
instructions that are stalled
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Cache $
• Cache can accelerate reads and make writes
longer and more complex
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Reordering and C++
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Reordering Types
• Data dependencies must be honored
• C++ compiler may reorder any memory access
under the as-if rule
• Different processors have different reordering
guaranties
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
AS-IF Rule
● Accesses (reads and writes) to volatile objects
occur strictly according to the semantics of the
expressions in which they occur. In particular, they
are not reordered with respect to other volatile
accesses on the same thread.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
AS-IF Rule
● At program termination, data written to files is
exactly as if the program was executed as written
● Prompting text which is sent to interactive devices
will be shown before the program waits for input
● Executing function from external libraries
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
AS-IF Rule - Not Always
● programs with undefined behaviour
● copy elision, the compiler may remove calls to
move and copy-constructor and destructors of
temporary objects even if those calls have side
effects
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Multi Threading and Reordering
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Reordering between two threads
Thread 1 Thread 2
flag1 = 1; flag2 = 1;
if (flag2 == 0){ if (flag1 == 0){
critical section} critical section}
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Sequential Consistency
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Sequential Consistency
● Result of any execution is the same as if the
operations of all the processors were executed in
some sequential order
● Operations of each individual processor appear in
the sequence in the order specified by the program
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
SQC: Do we Have It?
● SQC is very expensive
● Modern compilers do not offer it (for free)
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
What Does C++ and Modern CPU guarantee?
SC-DRF:
● A system guaranteeing DRF-SC must define specific
instructions called synchronizing instructions, which provide a
way to coordinate different processors (equivalently, threads)
● Programs use those instructions to create a “happens before”
relationship between code running on one processor and
code running on another.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Example:
Thread 1 Thread 2
Foo(Flag)
S(a) S(a)
Bar(Flag) Bar(Flag)
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Pop Quiz: can this happen?
Thread 1 Thread 2 Thread 3 Thread 4
x=1 x=2 y1 = x y3 = x
y2 = x y4 = x
y1=1,y2=2,y3=2,y4=1?
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Pop Quiz: can this happen?
y1=1,y2=2,y3=2,y4=1?
Thread 1 Thread 2 Thread 3 Thread 4
1: x = 1 4: x = 2 2: y1 = x 3: y4 = x
5: y2 = x 6: y3 = x
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Alex Dathskovsky |
[email protected] | www.linkedin.com/in/alexdathskovsky
Volatile
● Volatile is not a synchronization tool
● Volatile doesn’t affect threading
● It's not an atomic value
● It doesn’t add barriers
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Volatile: what is it good for?
● Tells the compiler it shouldn’t optimize the
memory reads and writes order.
● Alas the CPU can still reorder
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Volatile: Bad Example
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Volatile: Most uses deprecated with C++20
• Is += a single/atomic instruction? How
about ++?
• How many reads/writes are needed
for compare_exchange? What if it fails
• foo(int volatile n) int volatile foo() are
meaningless.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Volatile: Most uses deprecated with C++20
• For more information watch JF’s talk about it
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization cont
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Compiler Code Barriers
Prevent compiler from moving reads or writes
across the barrier
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Compiler Code Barriers
Prevent compiler from moving reads or writes
across the barrier
Thread 1 Thread 2
value = very_long_calc() while (not done){}
asm volatile(“mfence” ::: “memory”) asm volatile(“mfence” ::: “memory”)
done = true //do something
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Locks and Atomics
Most Locks and atomic operation will act like
barriers
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Understanding Memory Barriers /
Memory Ordering
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Acquire Semantics
• property that can only apply to operations
that read from shared memory, whether they
are read-modify-write operations or plain
loads. The operation is then considered
a read-acquire. Acquire semantics prevent
memory reordering of the read-acquire with
any read or write operation that follows it in
program order.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Acquire Semantics
Read-Acquire
All memory operations
stay below the line
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Release Semantics
• property that can only apply to operations
that write to shared memory, whether they are
read-modify-write operations or plain stores.
The operation is then considered
a write-release. Release semantics prevent
memory reordering of the write-release with
any read or write operation that precedes it in
program order.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Release Semantics
All memory operations
stay above the line
Write-Release
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Memory Barrier / Acquire Release Order
Read-Acquire
All memory operations
stay between the borders
Write-Release
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Sequential Consistency
• This is the default and the most strict mode. Enforcing
that all operations are seen in a globally consistent
order across all threads, as if they were executing in a
single sequential thread. This means that any read or
write operation that uses this memory order will be
sequenced before or after all other operations in the
program, providing a globally consistent view of
memory.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Sequential Consistency
SQC
All operations will be in
the same order
SQC
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
What's The Difference?
Thread 1 Thread 2 Thread 3 Thread 4
x = sr(1) y = sr(2) y1 = la(x) y3 = la(y)
y2 = la(y) y4 = la(x)
sr = store_release
la = load_acquire
T3: y1 = 1 y2 = 0
T4: y3 = 2 y4 = 0
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
What's The Difference?
Thread 1 Thread 2 Thread 3 Thread 4
x = ss(1) y = ss(2) y1 = ls(x) y3 = ls(y)
y2 = ls(y) y4 = ls(x)
ss = store_seq_cst
ls = load_seq_cst
T3: y1 = 1 y2 = 2
T4: y1 = 1 y2 = 2
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Relaxed Semantics
• This semantics offers the weakest guarantees
among memory ordering constraints. There are
no guarantees about the relative order of
memory accesses as observed by different
threads. This means that operations performed
by one thread might not be immediately visible
to other threads, and the order in which
operations appear to occur might not reflect the
actual order in which they were executed.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Relaxed Semantics
Relaxed
Everything is possible
Relaxed
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Consume Semantics
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Consume Semantics
designed to exploit data dependencies between
threads to provide synchronization guarantees.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Data Dependency Ordering
● Some CPU have to emit barriers to order between
memory instructions (armv7, risc v)
● Data dependencies make the order defined
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Data Dependency Ordering
● Data dependencies can be on memory and
chained
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Consume Semantics : How does it works
● The compiler exploit the data dependency chains
● Instructions have to carry-a-dependency (lucky it's
defined in the standard)
● to summarize: one evaluation carry-a-dependency if
value of the first is defined in the second evaluation as
an operand
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Example
a = atomic_bool_value{flase},
x=0
Thread 1 Thread 2
x=1
a.sr(true)
z = a.lc()
if (z) y = x
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Good Example
a = atomic_int*_value{null}
Thread 1 Thread 2
x=1
a.sr(&x)
z = a.lc()
if (z) y = *z
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Consume Semantics
Good news consume is almost like acquire, acquire
promises same things and its stronger.
Most compilers do not support consume and will
emit release-acquire
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
What may happen here ?
A1.store(4, release)
Y = A2.load(acquire)
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
What may happen here ?
Y = A2.load(acquire)
A1.store(4, release)
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Why is it possible ?
A1.store(4, release)
Y = A2.load(acquire)
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
What may happen here ?
Y = A2.load(acquire)
A1.store(4, release)
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
C++ Concurrency tools
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::thread
● Cross platform thread class
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
thread_local
●storge of the variable is defined by the thread
● helps with data races, each thread has its own copy
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
thread_local
● Please don't abuse it
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
thread_local
● Please don't abuse it
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::atomic
● Provides a portable way to perform low level
atomic operations
● No torn reads and no torn writes
● Provides read-acquire, write-release and full
memory barriers
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Atomic Memory Order
● memory_order_relaxed – there are no sync or
ordering constraints, only this operation is
guaranteed to be atomic
● memory_order_acquire
● memory_order_release
● memory_order_seq_cst – this will give us
sequential consistency, and this is the default
mode
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Atomic Memory Fence
Int a = 0
Thread 1 Thread 2
a = 42;
atomic_thread_fence(memory_order_release) atomic_thread_fence(memory_order_acquire)
int r2 = a ? a : -1;
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::atomic Without a Fence
Int a = 0
std::atomic<int> ready(0)
Thread 1 Thread 2
a = 42; int r1 = ready.load(memory_order_acquire)
ready.store(1, memory_order_release) int r2 = a ? a : -1;
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::atomic: Default
Int a = 0
std::atomic<int> ready(0)
Thread 1 Thread 2
a = 42; int r1 = ready
ready.store(1)
int r2 = a ? a : -1;
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::atomic Performance: Loads
● On X86 atomic loads are just loads
(primitive types)
● Can be more expansive and cause locking on
other systems
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::atomic Performance: Stores
● On X86 atomic stores use xchg, and it is a full
barrier
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::atomic Spinlock Example
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::atomic Spinlock Example Cont
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::atomic Spinlock Example
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::atomic<std::shared_ptr>
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Atomic Builtins
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Atomic Builtins
●Most Compilers have implementations for
C++11 compatible atomic operations
● GCC and Clang use the __atomic prefix
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Volatile vs Atomics
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Volatile vs Atomics
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
X86-64 disassembly
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
X86-64 32 bits disassembly
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
X86-64 32 bits disassembly
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
RISC V-64 disassembly
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
RISC V-32 disassembly
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Fence Example
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Relaxed
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Relaxed
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Relaxed
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Relaxed
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Relaxed
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Relaxed surprise
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Acquire
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Acquire
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Acquire No Surprises
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
RISC V Disassembly
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
RISC V Disassembly
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Other STL Concurrency Features
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
std::future and std::promise
● std::future<T> - value for which you may wait
● Std::promise<T> - produces a future
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Futures and Promises
● Can help communication between threads
● Help build task-oriented utilities for executing
work on different threads
● Future and promise are one shoot
operation
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Jthread
● Same as std::thread but is joinable by default
● Jthread is stoppable with std::stop_source
● Provides easier implementation where user don’t
have to think about joins
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools
● std::mutex, std::conditional_variable
● std::lock_guard – RAII helper for locking
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools
● std::unique_lock – same as lock guard but
unique and can be deferred.
● std::scoped_lock – takes ownership of multiple
locks at once with RAII with deadlock avoidance
algorithm
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools
● std::counting_semaphore – semaphore that can
be set to an arbitrary number.
● Std::binary_semaphore – same as
counting_semaphore but it's set to 1.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools : stop_source
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools : stop_source
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Std::threads : Micro Benchmark
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools - cont
● Std::latch– threads may block on latch until its
value is zero, latch is one shoot.
● std::barrier– very similar to latch but can be
used multiple times .
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools – Latch Example
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools – Latch Example
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools – Barrier Example
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools – Barrier Example
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools
● std::shared_mutex– may be used by couple of
threads or be exclusive.
● std::timed_mutex – same as mutex but has a
claim time out.
● std::shared_timed_mutex – combination of
shared and timed mutexes.
● std::shared_lock – RAII wrapper for timed and
shared mutexes
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools
● Static: from C++11 static variables initialization
is magic
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools
● std::call_once and std::once_flag – help to do
something just once.
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
Synchronization Tools
● Std::packaged_task – wraps a callable into a
thread and returns a future
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
QUESTIONS
Alex Dathskovsky | [email protected] | www.linkedin.com/in/alexdathskovsky
THANK YOU FOR LISTENING
ALEX DATSKOVSKY
+97254-7685001
[email protected]WWW.LINKEDIN.COM/IN/ALEXDATHSKOVSKY
https://www.cppnext.com