常规对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 datarelative 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更新的时候就会更新其他值,如果放的使数组中的某个值,编译器就会报错。
参考:
https://stackoverflow.com/questions/19687233/explict-flush-directive-with-openmp-when-is-it-necessary-and-when-is-it-helpful
https://stackoverflow.com/questions/14859219/openmp-flush-vs-flushlist