如何在没有外部标志的情况下仅在Fortran OpenMP循环中运行一次代码?

时间:2017-05-02 14:58:43

标签: fortran openmp fortran90

是否可以通过Fortran中的某种模式在循环迭代开始时只分配一次变量? 类似于下面的伪代码。我现在拥有的是一个If语句,它检查是否设置了一个标志,如果是,我们执行if语句。然后我们取消它,因为我的程序是并行的,我想避免在我的内部循环中的条件分支。从我所看到的可以用C ++做,但我想知道我是否能以某种方式在Fortran中实现相同的功能。

我在寻找:

!$OMP DO PRIVATE(variable)
DO i = 0, N = 100000

<Set Variable to a fixed value once and only once at the start of the iteration>

<CODE>

END DO
!$END OMP DO

我有什么

!$OMP DO PRIVATE(variable)
DO i = 1, N = 100000 

    IF (FLAG_IS_SET) THEN
       <Set variable>
       <UNSET_THE_FLAG>
    END IF

    <CODE>

END DO
!$END OMP DO

2 个答案:

答案 0 :(得分:2)

一个简单的解决方案是手动共享跨线程的迭代。假设100000是n_threads的倍数:

!$OMP PARALLEL PRIVATE(variable)
i_thread = omp_get_thread_num()
n_threads = omp_get_num_threads()
chunk_size = 100000 / n_threads
i_start = i_thread * chunk_size + 1
<Set variable>
DO i = i_start, i_start + chunk_size - 1
    <CODE>
END DO
!$OMP END PARALLEL

它避免了最内层循环中的条件分支,它可能接近编译器对静态调度的作用。

答案 1 :(得分:1)

我不清楚你要做什么。 如果你想做你所说的你做的事情(&#34;在循环迭代开始时只分配一次变量&#34;),这完全自然地落到了

!$OMP DO PRIVATE(variable)
DO i = 0, N = 100000
variable = f(i)        ! Assign value to the local variable at the start of each iteration
<CODE>
END DO
!$END OMP DO

由于变量是线程私有的,因此每个线程中都有一个副本,您可以为变量分配一次。

但这似乎很容易,也许我不明白你真正想做的事情!