0% found this document useful (0 votes)
21 views10 pages

L4a MM Examples

The document discusses the memory model in modern C++ and its implications for atomic operations and synchronization. It highlights the importance of avoiding data races and using synchronization mechanisms like mutexes and atomics. Several examples are provided to illustrate how different memory orders affect program behavior and visibility of operations across threads.

Uploaded by

Chang Jingyan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views10 pages

L4a MM Examples

The document discusses the memory model in modern C++ and its implications for atomic operations and synchronization. It highlights the importance of avoiding data races and using synchronization mechanisms like mutexes and atomics. Several examples are provided to illustrate how different memory orders affect program behavior and visibility of operations across threads.

Uploaded by

Chang Jingyan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Lecture 4a – Atomics and

Memory Model in Modern C++


Additional Examples & Questions

CS3211 L4a - Memory Model - Additional Examples 1


Outline
• Questions
• From the last weeks: atomic weapons

CS3211 L4a - Memory Model - Additional Examples 2


Language level memory models
• Modern (C++11) and not-so-modern (Java 5) languages guarantees
• Compilers will insert the necessary synchronization to cope with the hardware
memory model
• No guarantees if your program contains data races!
• The intuition is that most programmers would consider a racy program to be
buggy
• Use synchronization!
• L3: Mutex & condition variable
• L4: Atomics

CS3211 L4a - Memory Model - Additional Examples 3


Language-level vs. Hardware-level Memory Consistency Models

• Do single threaded apps benefit


from having a memory model?
• When do we use sequential, rel-
acq, relaxed ordering?

CS3211 L4a - Memory Model - Additional Examples 4


Initially: x = 0; y = 0; z = 0;

x = 0;
Example 1 Should this code ever print 0?

y = 0;
z = 0;
Thread 1: Thread 2: Thread 3:
x.store(1, memory_order_relaxed); while (y.load(memory_order_acquire)!=2); while (z.load(memory_order_acquire)!=4);

y.store(3, memory_order_relaxed);

y.store(2, memory_order_release); z.store(4, memory_order_release); cout << x.load(memory_order_relaxed);

x.store(5, memory_order_relaxed);

CS3211 L4a - Memory Model - Additional Examples 5


Example 1 Initially: x = 0; y = 0; z = 0;
Should this code ever print 0?
x = 0;
y = 0;
z = 0;
Thread 1: Thread 2: Thread 3:
x.store(1, memory_order_relaxed); while (y.load(memory_order_acquire)!=2); while (z.load(memory_order_acquire)!=4);

y.store(3, memory_order_relaxed);

y.store(2, memory_order_release); z.store(4, memory_order_release); cout << x.load(memory_order_relaxed);

x.store(5, memory_order_relaxed);

http://svr-pes20-cppmem.cl.cam.ac.uk/cppmem/
int main() {
atomic_int x=0;
atomic_int y=0;
atomic_int z=0;
{{{ { x.store(1, relaxed); y.store(2, release); }
||| { y.load(acquire).readsvalue(2); y.store(3, relaxed); z.store(4, release);
x.store(5, relaxed); }
||| { z.load(acquire).readsvalue(4); r1 = x.load(relaxed); }
CS3211 L4a - Memory Model - Additional Examples }}}; 6
return 0;
}
Initially: x = 0; y = 0; z = 0;
Should this code ever print 0?
x = 0;
Example 2
y = 0;
z = 0;
Thread 1: Thread 2: Thread 3:
x.store(1, memory_order_relaxed); r1 = y.load(memory_order_acquire); while (z.load(memory_order_acquire)!=4);

y.store(3, memory_order_relaxed);

y.store(2, memory_order_release); z.store(4, memory_order_release); cout << x.load(memory_order_relaxed);

x.store(5, memory_order_relaxed);

CS3211 L4a - Memory Model - Additional Examples 7


Initially: x = 0; y = 0; z = 0;
x is not atomic

x = 0;
Example 3 Should this code ever print 0?

y = 0;
z = 0; Thread 1: Thread 2: Thread 3:
x = 1 while (y.load(memory_order_acquire)!=2); while (z.load(memory_order_acquire)!=4);

y.store(3, memory_order_relaxed);

y.store(2, memory_order_release); z.store(4, memory_order_release); cout << x;

x = 3;

CS3211 L4a - Memory Model - Additional Examples 8


Initially: x = 0; y = 0; z = 0;

x = 0;
Example 4 Should this code ever print 0?

y = 0;
z = 0;
Thread 1: Thread 2: Thread 3:
x.store(1, memory_order_relaxed); while (y.load(memory_order_acquire)!=2); while (y.load(memory_order_acquire)!=2 );

x.store(3, memory_order_relaxed); cout << x.load(memory_order_relaxed);

y.store(2, memory_order_release); y.store(2, memory_order_release);

x.store(5, memory_order_relaxed);

CS3211 L4a - Memory Model - Additional Examples 9


Terminology
• In lecture 4
• We preferred to say “operation seen by a thread…”
• In general, memory model is explained by mentioning
• What ordering is allowed and what ordering is not allowed
• Visible side effects
• https://en.cppreference.com/w/cpp/atomic/memory_order
• CS3211 (language-level) memory model is a subset of the C++
memory model
• CS3211 does not include fences

CS3211 L4a - Memory Model - Additional Examples 10

You might also like