在下面的代码片段的消费者分支中,刷新用于观察自上次读取以来可能发生的对flag
的任何更改,但是在调用f()
之前不会刷新data
变量。
Q1:在调用f()
之前应该向消费者添加刷新吗?
Q2:如果在调用f()
之前假设data
不在消费者线程的L1缓存中,答案是否会改变?
#pragma omp parallel shared(data, flag)
{
if (omp_get_thread_num() == 0) { // Producer.
// Write to data and make visible to other thread.
data = computeData();
#pragma omp flush (data)
// Write to flag and make visible to other thread.
flag = 1;
#pragma omp flush (flag)
}
if (omp_get_thread_num() == 1) { // Consumer.
while (flag == 0) {
#pragma omp flush (flag)
; // No-op, flush reloads.
}
f(data); // Do something with data.
}
}
似乎我的类中使用的竞争条件的代码片段是从其他来源复制的。我同时阅读OpenMP共同核心[1],并发现了@MichaelKlemm推荐的使用atomic
的无种族等价物。我根据[1]中的图11.5修改了原始代码片段。
#pragma omp parallel shared(data, flag)
{
int temp = 0;
if (omp_get_thread_num() == 0) { // Producer.
// Write to data and make visible to other thread.
data = computeData();
#pragma omp flush
// Write to flag with atomic results in implicit flush.
#pragma omp atomic write
flag = 1;
}
if (omp_get_thread_num() == 1) { // Consumer.
while (!temp) {
#pragma omp atomic read
temp = flag; // Read into temp in case flag changes.
}
#pragma omp flush
f(data); // Do something with data.
}
}
[1] https://mitpress.mit.edu/books/openmp-common-core