我正在使用netlib LSODAR子例程来集成ODE。其代码为。该代码在F77中,并使用save语句和DATA构造。我不能只删除它们,并且代码要经过很长的时间,并且需要用每个选项进行编辑。我的代码需要运行多个这些集成,因此我想使用openmp来并行化代码。有什么办法可以使这些代码成为线程安全的?我已经将所有函数和子例程都递归了,并将所有输入变量添加到了子例程private / firstprivate,但这没有帮助。任何帮助表示赞赏。如果还有其他线程安全的替代方法也可以。
一个样本将是
program main
!$omp parallel
call counter()
call counter()
!$omp end parallel
end program main
subroutine counter()
integer i
save i
i = i+1
end subroutine counter
我无法干预save语句,并且还有一些常见的块。在我理想的情况下,最后每个线程中的i应该为2。但是,在这种情况下,它只会导致(处理器数量)* 2。
答案 0 :(得分:0)
在没有实际示例说明您想要实现什么以及并行化应如何表现的情况下,很难回答这个问题。
我可以给出一个一般性的提示,以查看将数据私有化的OpenMP结构。在您的特定情况下,您想私有化全局数据,因此需要threadprivate
指令(OpenMP API 5.0规范中的第2.19.2节)和copyin
/ copyout
指令( 2.19.6)。
编辑:
添加代码示例后,您可以通过在代码中添加atomic
指令来使代码具有线程安全性:
subroutine counter()
integer i
save i
!$omp atomic
i = i+1
!$omp end atomic
end subroutine counter
这将确保所有线程都将更新变量的单个副本,而不会出现竞争条件。
如果您要按线程复制该变量的一个副本,则必须执行以下操作:
subroutine counter()
integer i
save i
!$omp threadprivate(i)
i = i+1
end subroutine counter
然后可以使用copyin
和copyout
将值移到i
的线程专用副本中。