OpenMP生产者-消费者使用flush



在下面的代码片段的消费者分支中,刷新用于观察自上次读取以来可能发生的对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

最新更新