[英]C++11 memory_model_relaxed and memory_order_seq_cst relation
Hi I am trying to understand lock-free work stealing dequeue implementation.嗨,我正在尝试了解无锁工作窃取出队实现。 Currently, I am reading one implementation by google's filament here .目前,我对谷歌的长丝读一个实现此。 I am mostly concerned about the steal operation.我最关心的是窃取操作。
template <typename TYPE, size_t COUNT>
TYPE WorkStealingDequeue<TYPE, COUNT>::steal() noexcept {
do {
// mTop must be read before mBottom
int32_t top = mTop.load(std::memory_order_seq_cst);
// mBottom is written concurrently to the read below in pop() or push(), so
// we need basic atomicity. Also makes sure that writes made in push()
// (prior to mBottom update) are visible.
int32_t bottom = mBottom.load(std::memory_order_acquire);
if (top >= bottom) {
// queue is empty
return TYPE();
}
// The queue isn't empty
TYPE item(getItemAt(top));
if (mTop.compare_exchange_strong(top, top + 1,
std::memory_order_seq_cst,
std::memory_order_relaxed)) {
// success: we stole a job, just return it.
return item;
}
// failure: the item we just tried to steal was pop()'ed under our feet,
// simply discard it; nothing to do.
} while (true);
}
I am wondering whether it's correct to replace the initial mtop.load memory order to memory_order_relaxed and the subsequent mBottom.load memory order to memory_order_seq_cst.我想知道将初始的 mtop.load 内存顺序替换为 memory_order_relaxed 并将随后的 mBottom.load 内存顺序替换为 memory_order_seq_cst 是否正确。 This should still preserve the mtop.load and mBottom.load order right?这应该仍然保留 mtop.load 和 mBottom.load 顺序对吗? memory_order_seq_cst flag should still prevent memory_order_relaxed to be reordered pass the the load operation right? memory_order_seq_cst 标志应该仍然阻止 memory_order_relaxed 通过加载操作重新排序吗?
You should reason about the code in terms of the order in which the memory operations are allowed to occur in order to maintain correctness, as well as how these orderings affect inter-thread synchronization.您应该根据允许内存操作发生的顺序来推理代码以保持正确性,以及这些顺序如何影响线程间同步。 The C++ std::memory_order
standard allows the programmer to express such constraints and leaves it up to compiler to emit the necessary memory fences to realize these constraints. C++ std::memory_order
标准允许程序员表达这样的约束,并让编译器发出必要的内存栅栏来实现这些约束。
The code already expresses exactly what it needs to do: sequence mTop.load()
before mBottom.load()
and synchronize the mBottom.store()
in push()
with mBottom.load()
in steal()
.该代码已经表示正是它需要做的:序列mTop.load()
之前mBottom.load()
和同步mBottom.store()
在push()
与mBottom.load()
在steal()
Yes, I agree with your conclusion that you can relax the operations on top, but you have to make the operation on bottom sequentially consistent.是的,我同意你的结论,你可以放宽顶部的操作,但你必须使底部的操作顺序一致。 In fact, that is how I have implemented my chase-lev workstealing dequeue: https://github.com/mpoeter/xenium/blob/master/xenium/chase_work_stealing_deque.hpp事实上,这就是我如何实现我的 Chase-lev 作品窃取出队: https : //github.com/mpoeter/xenium/blob/master/xenium/chase_work_stealing_deque.hpp
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.