【问题标题】:Fortran, Open MP, indirect recursion, and limited stack memoryFortran、Open MP、间接递归和有限的堆栈内存
【发布时间】:2019-04-28 19:15:27
【问题描述】:

关于堆栈空间问题、OpenMP 以及如何处理它的其他帖子有很多回复。但是,我找不到信息来真正理解 OpenMP 调整编译器选项的原因:

gfortran 中的-fopenmp 暗示-frecursive 背后的原因是什么?

文档说:

通过强制将所有本地数组分配到堆栈上来允许间接递归

但是,我没有上下文来理解这一点。为什么并行化需要间接递归?

为什么并行化希望所有本地数组都在堆栈上?

我希望了解,因此我知道覆盖这些选项的后果,例如使用 -fmax-stack-var-size=n,以避免堆栈溢出问题。

【问题讨论】:

  • "为什么并行化希望所有本地数组都在堆栈上?" 通过使用堆栈数组,它会自动使它们成为线程安全的,在每个线程都有的线程区域中它自己的堆栈,通常也足够分开以避免错误共享的锁。

标签: fortran openmp gfortran


【解决方案1】:

如果没有 -frecursive,编译器会将超过限制的局部变量 -fmax-stack-var-size= 放入静态内存而不是堆栈中。也就是说,它们的行为就像它们具有 SAVE 属性一样,并且它们在所有线程之间共享。这些语义对于多线程程序是没有意义的,因此 -fopenmp 意味着 -frecursive。

由于多线程程序的日益普及,并且由于 F2018 指定过程默认为递归,因此此行为将在 GFortran 的未来版本中发生变化,很可能在超过堆栈大小限制时切换到堆分配变量而不是使用静态内存。但就目前而言,这不是一个选择。

【讨论】:

  • OK 所以关键是每个线程都有自己的堆栈空间,在那里它保留自己的局部变量副本。而在静态内存中,所有线程共享相同的变量,因此不安全。除了变量分配的信息之外,您还可以帮助我理解为什么他们甚至提到“间接递归”吗?
  • @midnightGreen 嗯,不确定,但我猜这是由于许多代码使用间接递归来绕过递归被禁止的限制(因为编译器通常不可能诊断间接递归,但相对直接注意到直接递归并生成错误消息)。
猜你喜欢
  • 2014-01-02
  • 2018-09-24
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 2015-04-04
相关资源
最近更新 更多