常规对flush制导语句的解释为:用以标记一个同步点,用以确保所有的线程看到一致的存储器视图。这样的解释对一般人来讲很难理解,其实它的功能就是强制刷新每个线程的临时视图,使其和内存视图保持一致,即:使线程中缓存的变量值和内存中的变量值保持一致。一般在使用OpenMP的时候也很少遇到flush语句。这是因为flush在下面几种情况下会隐含运行(nowait子句除外):
Barrier
critical:进入与退出部分
ordered:进入与退出部分
parallel:退出部分
for:退出部分
sections:退出部分
single:退出部分
然而,在主从模式下,flush的使用就很有必要了,下面是一个具体实例。
//http://www.openmp.org/wp-content/uploads/openmp-examples-4.0.2.pdf
//Example mem_model.2c, from Chapter 2 (The OpenMP Memory Model)
int main() {
int data, flag = 0;
#pragma omp parallel num_threads(2)
{
if (omp_get_thread_num()==0) {
/* Write to the data buffer that will be read by thread */
data = 42;
/* Flush data to thread 1 and strictly order the write to data
relative to the write to the flag */
#pragma omp flush(flag, data)
/* Set flag to release thread 1 */
flag = 1;
/* Flush flag to ensure that thread 1 sees S-21 the change */
#pragma omp flush(flag)
}
else if (omp_get_thread_num()==1) {
/* Loop until we see the update to the flag */
#pragma omp flush(flag, data)
while (flag < 1) {
#pragma omp flush(flag, data)
}
/* Values of flag and data are undefined */
printf("flag=%d data=%d\n", flag, data);
#pragma omp flush(flag, data)
/* Values data will be 42, value of flag still undefined */
printf("flag=%d data=%d\n", flag, data);
}
}
return 0;
}
在上面代码中,data和flag两个变量的值会在线程0中改变,为了使线程1能看到改变后的data和flag就需要使用flush语句使其缓存中的data和flag值强制刷新。
另外,flush()列表中只能放单个的变量,不能放数组中的某个值,eg:#pragma omp flush(seed_by_age[agents[i].ageGroup])
因为缓存更新只能是以cache line的形式存在,如果进行flush更新的时候就会更新其他值,如果放的使数组中的某个值,编译器就会报错。
### 在omp sentions语句下时也会遇到这种问题,所以在sention语句下也需要注意是否需要flush语句。
参考:
https://stackoverflow.com/questions/14859219/openmp-flush-vs-flushlist

本文详细介绍了 OpenMP 中的 flush 指令,它用于强制线程间的内存一致性。在多线程环境中,flush 使得线程缓存中的变量值与内存中的保持一致。通常在特定的 OpenMP 结构如 barrier、critical 和 ordered 等中隐含执行 flush。文中通过一个主从模式的例子展示了 flush 的必要性,强调了在特定场景下如何正确使用 flush 以避免线程间的数据不一致。此外,还提到 flush 不适用于数组元素,并列举了相关参考资料。
&spm=1001.2101.3001.5002&articleId=108876099&d=1&t=3&u=b2980d34170a40758ac5b741bdb4642b)
1万+

被折叠的 条评论
为什么被折叠?



