# Memory Consistency

Some architectures, such as Intel® IA-64 (Itanium®), have "weak memory consistency", in which memory operations on different addresses may be reordered by the hardware for sake of efficiency. The subject is complex, and it is recommended that the interested reader consult other works (Intel 2002, Robison 2003) on the subject. If you are programming only for IA-32 and Intel® 64 architecture platforms, you can skip this section.

Class `atomic`<T> permits you to enforce certain ordering of memory operations as described in the following table.

Ordering Constraints
Kind | Description | Default For
--- | --- | ---
`acquire` | Operations after the atomic operation never move over it. | read
`release` | Operations before the atomic operation never move over it. | write
sequentially consistent | Operations on either side never move over the atomic operation and the sequentially consistent atomic operations have a global order. | `fetch_and_store` `fetch_and_add` `compare_and_swap`

The rightmost column lists the operations that default to a particular constraint. Use these defaults to avoid unexpected surprises. For read and write, the defaults are the only constraints available. However, if you are familiar with weak memory consistency, you might want to change the default sequential consistency for the other operations to weaker constraints. To do this, use variants that take a template argument. The argument can be `acquire` or `release`, which are values of the enum type `memory_semantics`.

For example, suppose various threads are producing parts of a data structure, and you want to signal a consuming thread when the data structure is ready. One way to do this is to initialize an atomic counter with the number of busy producers, and as each producer finishes, it executes:

    refcount.fetch_and_add<release>(-1);

The argument `release` guarantees that the producer's writes to shared memory occurs before `refcount` is decremented. Similarly, when the consumer checks `refcount`, the consumer must use an `acquire` fence, which is the default for reads, so that the consumer's reads of the data structure do not happen until after the consumer sees `refcount` become 0.

Parent topic: Atomic Operations