【发布时间】:2019-10-06 03:19:00
【问题描述】:
您好,我正在尝试了解无锁工作窃取出队的实现。目前,我正在阅读谷歌灯丝here 的一种实现。我最关心的是窃取操作。
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);
}
我想知道将初始 mtop.load 内存顺序替换为 memory_order_relaxed 并将随后的 mBottom.load 内存顺序替换为 memory_order_seq_cst 是否正确。这仍然应该保留 mtop.load 和 mBottom.load 顺序对吗? memory_order_seq_cst 标志应该仍然防止 memory_order_relaxed 被重新排序通过加载操作吧?
【问题讨论】:
-
C/C++ 语义不处理“重新排序”。任何基于“重新排序”的推理都可能适用于当今的实际实现,但不适用于标准。
-
请贴出完整的MT代码,即所有发布和消费数据的部分。
标签: c++ producer-consumer deque memory-model stdatomic