Damon's Blog
  • Damon's Blog
  • 💻Tech
    • Understand C++ Special Member Function Generation
    • Understand C++ Template Type Deduction
    • Using Windows Keymap in Mac and Intellij
    • Setup C++ Dev Env in MacOS using Docker
    • Floating-point Arithmetic
    • Java HFT Toolbox
    • Interesting Bitwise Operation
    • Python Metaclass
    • Memory Order
    • Grind 75+
      • Array
      • String
      • Matrix
      • Binary Search
      • Graph
      • Tree
      • Math
      • Hash Table
      • Recursion
      • Linked List
      • Stack
      • Heap
      • Trie
      • Dynamic Programming
      • Binary Operation
    • C++ for Java Developers
    • Typical Domain Driven Design Application Architecture
    • How to Deploy Applications in Linux Properly
    • Design Patterns with Java Examples
    • Tools for Reliability
    • MVCC in Database
    • Two Microservice Tech Stacks
    • The Difference between 127.0.0.1 and 0.0.0.0
  • âž—Math
    • Local Volatility in Terms of Implied Volatility
    • Mean and Variance of Squared Gaussian
    • A Simple Explanation of Information Gain
  • 💲Trading
    • Understanding Risk-Neutral Density Functions
    • The Deriving of Black-Scholes Equation
    • Quant Questions
  • 💎Gems
    • 2024
  • 📖Books
    • Performance Analysis and Tuning on Modern CPUs
Powered by GitBook
On this page
  • Memory Order in CPP
  • memory_order_relaxed
  • memory_order_acquire
  • memory_order_consume
  • memory_order_release
  • memory_order_acq_rel
  • memory_order_seq_cst
  • Memory Order in Java
  • Reference

Was this helpful?

  1. Tech

Memory Order

PreviousPython MetaclassNextGrind 75+

Last updated 1 year ago

Was this helpful?

Memory Order in CPP

std::atomic<size_t>         enqueue_pos_;
pos = enqueue_pos_.load(std::memory_order_relaxed);

The above example coms from .

The order of instruction execution is important. The compiler / java VM and the CPU are allowed to reorder instructions in the program for performance reasons, as long as the semantic meaning of the instructions remain the same. For instance, look at the following instructions,

int a = 1;
int b = 2;

a++;
b++;

These instructions could be reordered to the following sequence without losing the semantic meaning of the program:

int a = 1;
a++;

int b = 2;
b++;

There are different options when loading the atomic variable, this blog is to discuss the difference between them.

memory_order_relaxed

This memory ordering option provides the fewest ordering guarantees. It allows the greatest level of optimization freedom for the compiler and the CPU. It does not enforce any synchronization or ordering constraints on other memory accesses. It is useful in situations where strict ordering is not required or when the synchronization is handled through other means (e.g., locks or other synchronization primitives).

This type of atomic operation can have various optimizations performed on them, and they do not guarantee an order concerning locking and normal memory accesses.

memory_order_acquire

Reads from and writes to other variables cannot be reordered to occur before a read of a volatile variable, if the reads / writes originally occurred after the read of the volatile variable.

Notice that it is possible for reads of other variables that occur before the read of a volatile variable can be reordered to occur after the read of the volatile. Just not the other way around.

From before to after is allowed, but from after to before is not allowed.

memory_order_consume

This performs the same operation as memory_order_acquire, except that the ordering guarantees only apply to dependent data.

memory_order_release

Reads from and writes to other variables cannot be reordered to occur after a write to a volatile variable, if the reads / writes originally occurred before the write to the volatile variable.

The reads / writes before a write to a volatile variable are guaranteed to "happen before" the write to the volatile variable. Notice that it is still possible for e.g. reads / writes of other variables located after a write to a volatile to be reordered to occur before that write to the volatile. Just not the other way around.

From after to before is allowed, but from before to after is not allowed.

memory_order_acq_rel

This is a hybrid of memory_order_acquire and memory_order_release. Unlike the sequentially consistent model, this hybrid applies a happens-before relationship to dependent variables. This variant allows the synchronization requirements between independent readings and writes to be relaxed.

memory_order_seq_cst

This operates when all access to memory (that may have visible side effects on the other threads involved) has already happened. This is the strictest memory order variant. Thus, it guarantees the most negligible unexpected side effects between the thread interactions through non-atomic memory accesses.

Memory Order in Java

Reference

Check the README and example in .

💻
Bounded MPMC queue
RingBuffer
Memory Ordering for Atomic Operations in C++0x
Acquire and Release Fences
What is memory_order in C?
The Purpose of memory_order_consume in C++11
False Sharing
Java Volatile Keyword
ManyToManyConcurrentArrayQueue
mpmc_queue