gpt4 book ai didi

fortran - 数组的段错误,但仅限于派生类型的组件

转载 作者:行者123 更新时间:2023-12-02 14:55:24 24 4
gpt4 key购买 nike

非常简单的设置,在 Linux(红帽)上使用 gfortran 4.8.5:

  • 如果我的实数数组(在派生类型内)的大小 > 2,000,000,则会出现段错误。这似乎是一个标准的堆栈/堆问题,因为如果我使用 ulimit 检查,我的堆栈大小为 8mb。

  • 如果数组位于派生类型内,则没有问题

  • 请注意,正如 @francescalus 猜测的那样,删除初始值 = 0.0 可以消除问题

编辑添加:请注意,我已经发布了后续问题 Segmentation fault related to component of derived type这代表了一个更现实的用例,并进一步缩小了发生这种情况的条件。

program main

call sub1 ! seg fault if col size > 2,100,000
call sub2 ! works fine at col size = 100,000,000

end program main

subroutine sub1

type table
real :: col(2100000) = 0.0 ! works if "= 0.0" removed
end type table

type(table) :: table1
table1%col = 1.0

end subroutine sub1

subroutine sub2
real :: col(100000000) = 0.0
col = 1.0
end subroutine sub2

这里有一些明显的问题:

  • 这是预期的行为,还是较新版本的 gfortran 中修复的某些错误?

  • 我在这里遵循标准的 Fortran 操作程序,还是做错了什么?

  • 避免这种情况的建议方法是什么(请假设我在短期内无法更新到较新版本的 gfortran)?由于与此问题无关的原因,我几乎肯定会使用可分配数组组件来解决,但这可能不是一个理想的通用解决方案,我想知道我在这里拥有的所有好的选择。

  • 特别是,初始化派生类型的组件是不好的做法吗?

最佳答案

这可能是由于堆栈不足而导致的运行时问题,而不是 gfortran 的错误。

Gfortran 使用堆栈来存储自动数组和其他初始化数据。如果代码在此类数组较小时不会产生问题,但在数组大小增加时会出现段错误,则可能的原因是堆栈不足。

在最新版本的 gfortran 中,这个问题似乎是相同的。我用 gfortran 4.8.4、4.9.3、5.5.0、6.4.0、7.3.0 和 8.2.0 编译并运行了你的程序。在所有情况下,我都在默认堆栈大小的情况下获得了段错误,但当堆栈大小稍微增加时没有错误。

$  ./sfa
Segmentation fault
$ ulimit -s
8192
$ ulimit -s 8256
$ ./sfa && echo "DONE"
DONE

运行可能会解决您的问题

$ ulimit -s unlimited

在执行二进制文件之前。我不知道这样做有什么特别的惩罚,但更了解内存管理细节的程序员(例如编译器开发人员)可能会有不同的想法。

初始化派生类型的组件并不是一个坏习惯,但正如您所看到的,如果组件是一个大数组,它可能会导致堆栈出现问题 - 无论是由于组件本身的存储,还是由于存储内存以处理分配的 RHS。如果组件可分配并在子例程中分配,则数组将存储在堆中而不是堆栈中,通常可以避免此问题。在这种情况下,它可能是在子例程中而不是在编译时实际动态设置数组的值。它可能不太优雅,但我认为这是值得的,因为它是代码开发工作的典型示例,可以防止执行二进制文件时出现可避免的、与环境相关的错误。

您的上述代码符合标准。正如评论中所解释的,缺乏子例程的显式接口(interface)并不是一个好的做法,但对于这些简单的子例程来说,这并不违反规则。

某些编译器具有允许您更改某些对象在内存中分配位置的标志。虽然它可以解决特定问题,但标志取决于编译器,并且在比较不同编译器时通常不等效。根据我的经验,通过可分配项使用动态内存是一个更强大的解决方案。

最后,请注意,如果您使用 OpenMP,上面的 ulimit 命令仅影响主线程 - 您需要通过环境变量 OMP_STACKSIZE 设置其他每个线程的堆栈大小,不能是无限制。请记住,非主线程耗尽堆栈是一个更难以诊断的问题,因为二进制文件可能会在没有适当的段错误错误的情况下停止。

关于fortran - 数组的段错误,但仅限于派生类型的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51986069/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com