问题描述
我读过文章“Correct and Efficient Work-Stealing for Weak Memory Models”,其中作者给出了以下代码:
int take(Deque *q) {
size_t b = load_explicit(&q->bottom,relaxed) - 1;
Array *a = load_explicit(&q->array,relaxed);
store_explicit(&q->bottom,b,relaxed);
thread_fence(seq_cst);
size_t t = load_explicit(&q->top,relaxed);
int x;
if (t <= b) {
/* Non-empty queue. */
x = load_explicit(&a->buffer[b % a->size],relaxed);
if (t == b) {
/* Single last element in queue. */
if (!compare_exchange_strong_explicit(&q->top,&t,t + 1,seq_cst,relaxed))
/* Failed race. */
x = EMPTY;
store_explicit(&q->bottom,b + 1,relaxed);
}
} else { /* Empty queue. */
x = EMPTY;
store_explicit(&q->bottom,relaxed);
}
return x;
}
void push(Deque *q,int x) {
size_t b = load_explicit(&q->bottom,relaxed);
size_t t = load_explicit(&q->top,acquire);
Array *a = load_explicit(&q->array,relaxed);
if (b - t > a->size - 1) { /* Full queue. */
resize(q);
a = load_explicit(&q->array,relaxed);
}
store_explicit(&a->buffer[b % a->size],x,relaxed);
thread_fence(release);
store_explicit(&q->bottom,relaxed);
}
int steal(Deque *q) {
size_t t = load_explicit(&q->top,acquire);
thread_fence(seq_cst);
size_t b = load_explicit(&q->bottom,acquire);
int x = EMPTY;
if (t < b) {
/* Non-empty queue. */
Array *a = load_explicit(&q->array,consume);
x = load_explicit(&a->buffer[t % a->size],relaxed);
if (!compare_exchange_strong_explicit(&q->top,relaxed))
/* Failed race. */
return ABORT;
}
return x;
}
如我们所见,在窃取操作中,他们使用 seq_cst
围栏。此外,他们在采取行动时使用这个围栏。我有两个问题:
- 为什么我们在窃取操作中需要这个围栏:你能解释一些情况的分步示例,在这种情况下,如果没有这个围栏,我们会得到未定义的行为或竞争条件?
- 为什么我们不能在 take 操作中替换这个栅栏,仅仅通过释放内存存储(或栅栏)操作(到底部变量,又名
b
)?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)