简体   繁体   English

C ++ 11内存排序 - 差异?

[英]C++11 memory orderings- the differences?

I am currently reading Concurrency in Action and on page 111 it gives this sample code relating to a std::atomic_flag in order to explain how memory orderings work: 我目前正在阅读Concurrency in Action和第111页,它提供了与std::atomic_flag相关的示例代码,以解释内存排序的工作原理:

f.clear(std::memory_order_release);
bool x = f.test_and_set();

but all it says is: 但它说的是:

Here, the call to clear() explicitly requests that the flag is cleared with release semantics, while the call to test_and_set() uses the default memory ordering for setting the flag and retrieving the old value. 这里,对clear()的调用显式请求使用释放语义清除该标志,而对test_and_set()的调用使用默认的内存顺序来设置标志并检索旧值。

They haven't actually explained what the differences are. 他们实际上没有解释这些差异是什么。 Could somebody provide a general overview of how these memory orderings work? 有人可以提供这些内存排序如何工作的一般概述吗? So not just the one I have mentioned above, but I believe there are a few more: 所以不仅仅是我上面提到的那个,但我相信还有一些:

memory_order_relaxed
memory_order_release
memory_order_seq_cst
memory_order_consume
memory_order_acquire
memory_order_acq_rel

Informal characterisation (take it with a sack of salt): 非正式表征(用一袋盐服用):

  • SEQ_CST: the code behaves as if it was a simple interleaving of threads, with no reordering observable, as long as there are no data races. SEQ_CST:只要没有数据争用 ,代码就像是一个简单的线程交错一样,没有重新排序的可观察性。
  • RELEASE/ACQUIRE: A release "publishes" a write, and a read on that same memory location synchronizes with that write. RELEASE / ACQUIRE:发布“发布”一个写,并且该相同内存位置的读取与该写同步。 As an example, a mutex lock may do an ACQUIRE , and a mutex unlock a RELEASE . 例如,互斥锁可以执行ACQUIRE ,互斥锁可以解锁RELEASE Another example: 另一个例子:

Example (atomic operations marked with their memory order on parenthesis): 示例(在括号上标记其内存顺序的原子操作):

t1:                                   t2:
   data = foo                            while not data_valid; (ACQUIRE)
   data_valid = true; (RELEASE)          bar = data;
  • ACQ_REL: does both an acquire and a release, for atomic RMW (Read-Modify-Write) operations. ACQ_REL:对原子RMW(读 - 修改 - 写)操作进行获取和释放。 Note that you can specify to use ACQ_REL for a sucessful RMW, and another memory order if the RMW operation fails. 请注意,您可以指定将ACQ_REL用于成功的RMW,如果RMW操作失败,则指定另一个内存顺序。
  • RELEASE/CONSUME: You publish a pointer to a structure, and a read "consumes" that publication, and can access the pointed-to data. RELEASE / CONSUME:您发布一个指向结构的指针,并且读取“消耗”该发布,并且可以访问指向的数据。 Some Alpha processors had split caches, which meant that you could be reading a pointer from a bank of a cache, and the pointed-to data may not be still on other bank from that cache. 一些Alpha处理器具有拆分缓存,这意味着您可能正在从缓存库中读取指针,并且指向的数据可能不会仍然存在于该缓存的其他存储库中。 In RCU as implemented on Linux, rcu_derefence() takes care of inserting a read barrier on Alpha between the read of the pointer and its dereference. 在Linux上实现的RCU中, rcu_derefence()负责在读取指针和取消引用之间在Alpha上插入读屏障。 Note that there has been some talk on totally changing the specification of the consume memory order (on a mailing list thread called "arch: atomic rework" ), as it seems to be impractical for compiler writers. 请注意,有一些关于完全改变消耗内存顺序规范的讨论(在名为“arch:atomic rework”的邮件列表线程上),因为它似乎对编译器编写者来说是不切实际的。 In particular, the current standard allows you to publish p , and *(q + (pp)) is dependant on that. 特别是,当前标准允许您发布p ,而*(q + (pp))依赖于此。 Some people contend that makes no sense at all. 有些人认为这完全没有意义。
  • RELAXED: Free for all. 放松:对所有人免费。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM