简体   繁体   English

混合松弛和释放-获取内存指令

[英]Mixing Relaxed and Release-Acquire Memory Orders

Consider std::atomic<int> x(0) .考虑std::atomic<int> x(0) If I understand correctly, std::memory_order_relaxed guarantees only that the operation happens atomically, but provides no guarantees of synchronization.如果我理解正确, std::memory_order_relaxed仅保证操作以原子方式发生,但不提供同步保证。 So x.fetch_add(1, std::memory_order_relaxed) 1000 times from 2 threads will have an end result of 2000 always.因此x.fetch_add(1, std::memory_order_relaxed)来自 2 个线程的x.fetch_add(1, std::memory_order_relaxed) 1000 次将始终具有 2000 的最终结果。 However, the returned value of any one of those calls is not guaranteed to reflect the true current value (eg the 2000th increment could return 1700 as the previous value).但是,这些调用中的任何一个的返回值都不能保证反映真实的当前值(例如,第 2000 次增量可能返回 1700 作为前一个值)。

But - and here's my confusion - given that those increments are happening in parallel, what would x.load(std::memory_order_acquire) return?但是 - 这就是我的困惑 - 鉴于这些增量是并行发生的, x.load(std::memory_order_acquire)返回什么? Or x.fetch_add(1, std::memory_order_acq_rel) ?还是x.fetch_add(1, std::memory_order_acq_rel) Do these return the true current value or do they have the same problem of out-of-date answers that relaxed ordering has due to the relaxed increments?这些是否返回真实的当前值,或者它们是否具有由于宽松的增量而导致的宽松排序所具有的过时答案的相同问题?

As far as I can tell, the standard only guarantees that releasing to an acquire (on the same variable) synchronizes and thus gives the true current value.据我所知,该标准仅保证释放到获取(在同一变量上)同步并因此给出真实的当前值。 So how can relaxed mix in with typical acquire-release semantics?那么如何轻松混合典型的获取-释放语义呢?

For instance, I've heard std::shared_ptr 's reference count is incremented in relaxed order and decremented in acq_rel order because it needs to ensure it has the true value in order to only delete the object once.例如,我听说std::shared_ptr的引用计数以宽松的顺序递增并以 acq_rel 的顺序递减,因为它需要确保它具有真值以便只删除一次对象。 Because of this I'm tempted to think they would give the true current value, but I can't seem to find any standardese to back it up.因此,我很想认为他们会给出真实的当前值,但我似乎找不到任何标准来支持它。

ISO C++ guarantees that a modification order exists for every atomic object separately. ISO C++ 保证对每个原子对象分别存在一个修改顺序。

With seq_cst there's guaranteed to be a global order where all threads can agree on a changing before b or something.随着seq_cst还有的保证是一个全球性的秩序,所有线程能够同意a之前,改变b或东西。 But for a single object, a modification order is guaranteed to exist even if some operations are relaxed.但是对于单个对象,即使放宽了一些操作,也保证存在修改顺序。

The return values you from relaxed fetch_add define / record what the modification order was.您从轻松的fetch_add返回值定义/记录修改顺序是什么。 The 2000th increment returns 2000 by definition , that's how you know it was the 2000th.根据定义,第 2000 次增量返回2000 ,这就是您知道它是第 2000 次的方式。

As far as I can tell, the standard only guarantees that releasing to an acquire (on the same variable) synchronizes and thus gives the true current value.据我所知,该标准仅保证释放到获取(在同一变量上)同步并因此给出真实的当前值。

Synchronizes-with is only necessary if you care about reading other values, eg one thread stores to a non-atomic array, then does a release-store like data_ready = 1;只有当您关心读取其他值时才需要同步,例如,一个线程存储到非原子数组,然后执行像data_ready = 1;这样的释放存储data_ready = 1; . . For a reader to safely read data from the array, they need to see data_ready != 0 with an acquire load, which means they can also see the effects of all earlier assignments in the thread that did the release-store.为了让读者安全地从数组中读取数据,他们需要在获取加载时看到data_ready != 0 ,这意味着他们还可以看到执行释放存储的线程中所有早期分配的效果。

暂无
暂无

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

相关问题 宽松原子操作的内存模型释放/获取模式交互 - Memory model release/acquire mode interactions of relaxed atomic operations 单个编写器+阅读器的发布/检查更新类是否可以使用memory_order_relaxed或获取/释放以提高效率? - Could this publish / check-for-update class for a single writer + reader use memory_order_relaxed or acquire/release for efficiency? 获取/释放内存订购 - Acquire/Release Memory Ordering 抢先式多任务处理是否可以干扰C ++ 11发行获得语义? - Could preemptive multitasking interfere with C++11 release-acquire semantics? std::mutex 的发布-获取可见性保证是否仅适用于关键部分? - Do the release-acquire visibility guarantees of std::mutex apply to only the critical section? 宽松的原子存储是否在发布前重新排序? (类似于加载/获取) - Are relaxed atomic store reordered themselves before the release? (similar with load /acquire) 获取/释放内存订购示例 - acquire/release memory ordering example 在C ++中,获取/释放原子访问与结合围栏的宽松访问之间是否有有效的区别? - In C++, is there any effective difference between a acquire/release atomic access and a relaxed access combined with a fence? 使用 memory_order_relaxed 进行存储,使用 memory_order_acquire 进行加载 - Using memory_order_relaxed for storing with memory_order_acquire for loading 获取/发布与顺序一致的内存顺序 - Acquire/Release versus Sequentially Consistent memory order
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM