【问题标题】:Fortran recursion segmentation faultsFortran 递归分段错误
【发布时间】:2013-08-23 09:28:17
【问题描述】:

我必须设计和实现一个 Fortran 例程来确定方格上簇的大小,递归地编写子例程似乎非常方便。但是,每当我的格子大小超过某个值(大约 200/边)时,子程序就会始终出现段错误。这是我的集群检测例程:

RECURSIVE SUBROUTINE growCluster(lattice, adj, idx, area)
    INTEGER, INTENT(INOUT)  :: lattice(:), area 
    INTEGER, INTENT(IN)     :: adj(:,:), idx

    lattice(idx) = -1
    area = area + 1

    IF (lattice(adj(1,idx)).GT.0) &
        CALL growCluster(lattice,adj,adj(1,idx),area)

    IF (lattice(adj(2,idx)).GT.0) &
        CALL growCluster(lattice,adj,adj(2,idx),area)

    IF (lattice(adj(3,idx)).GT.0) &
        CALL growCluster(lattice,adj,adj(3,idx),area)

    IF (lattice(adj(4,idx)).GT.0) &
        CALL growCluster(lattice,adj,adj(4,idx),area)
END SUBROUTINE growCluster

其中 adj(1,n) 表示站点 n 的北邻,adj(2,n) 表示西邻,依此类推。什么会导致不稳定的段错误行为?对于大晶格尺寸,集群是否“太大”?

【问题讨论】:

    标签: recursion fortran cluster-computing


    【解决方案1】:

    我认为您遇到了堆栈溢出。如果您的晶格每边超过 200 个单位,那就是 40,000 个单位,这意味着您要递归 40,000 次。根据您的堆栈大小和堆栈帧大小,您可能很容易用完堆栈空间。

    您必须将您的算法转换为使用较少堆栈空间的算法才能处理较大的格。 Wikipedia 提供了一些实现(在伪代码中)关于如何在不破坏堆栈的情况下进行洪水填充。

    【讨论】:

    • 这绝对是堆栈溢出——我开始使用(不是最佳的)ulimit -s 选项,并且“修复”了问题,尽管我认为其他洪水填充算法会解决从长远来看要好得多。感谢您的链接!
    • 在技术相关的上下文中应该有一个标记来表示“堆栈溢出”
    【解决方案2】:

    1) 您是否尝试过编译然后在打开下标范围检查的情况下运行?只是为了确保大尺寸不会泄露代码越过数组边界进入非法内存的错误。很容易检查。

    2) 关于您的程序内存不足的可能性:尝试增加每个进程的堆栈大小限制。如何做到这一点取决于操作系统——在这里搜索,或者谷歌,或者告诉我们你的操作系统。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-05
      • 2018-03-30
      • 1970-01-01
      • 2017-03-14
      • 1970-01-01
      相关资源
      最近更新 更多