Fortran、Open MP、间接递归和有限的堆栈内存
Fortran, Open MP, indirect recursion, and limited stack memory
关于stackspace、OpenMP、如何处理的问题,其他帖子上有很多回复。但是,我找不到信息来真正理解为什么 OpenMP 会调整编译器选项:
gfortran 中的 -fopenmp
暗示 -frecursive
的原因是什么?
文档说:
Allow indirect recursion by forcing all local arrays to be allocated on the stack
但是,我没有上下文可以理解这一点。为什么并行化需要间接递归?
为什么并行化需要所有本地数组都在堆栈上?
我想了解所以我知道覆盖这些选项的后果,比如说,用 -fmax-stack-var-size=n
,以避免堆栈溢出问题。
如果没有 -frecursive,编译器会将超过限制 -fmax-stack-var-size= 的局部变量放在静态内存中而不是堆栈中。也就是说,它们的行为就好像它们具有 SAVE 属性一样,并且它们在所有线程之间共享。这些语义对于多线程程序是无意义的,因此 -fopenmp 暗示 -frecursive.
由于多线程程序越来越流行,并且由于 F2018 指定过程默认是递归的,这种行为将在未来的 GFortran 版本中改变,很可能是在超过大小限制时切换到堆分配用于堆栈变量而不是使用静态内存。但目前,这不是一个选项。
关于stackspace、OpenMP、如何处理的问题,其他帖子上有很多回复。但是,我找不到信息来真正理解为什么 OpenMP 会调整编译器选项:
gfortran 中的 -fopenmp
暗示 -frecursive
的原因是什么?
文档说:
Allow indirect recursion by forcing all local arrays to be allocated on the stack
但是,我没有上下文可以理解这一点。为什么并行化需要间接递归?
为什么并行化需要所有本地数组都在堆栈上?
我想了解所以我知道覆盖这些选项的后果,比如说,用 -fmax-stack-var-size=n
,以避免堆栈溢出问题。
如果没有 -frecursive,编译器会将超过限制 -fmax-stack-var-size= 的局部变量放在静态内存中而不是堆栈中。也就是说,它们的行为就好像它们具有 SAVE 属性一样,并且它们在所有线程之间共享。这些语义对于多线程程序是无意义的,因此 -fopenmp 暗示 -frecursive.
由于多线程程序越来越流行,并且由于 F2018 指定过程默认是递归的,这种行为将在未来的 GFortran 版本中改变,很可能是在超过大小限制时切换到堆分配用于堆栈变量而不是使用静态内存。但目前,这不是一个选项。