【问题标题】:Stack problems when copying from array to another in Fortran?在 Fortran 中从数组复制到另一个数组时出现堆栈问题?
【发布时间】:2020-02-27 23:04:02
【问题描述】:

如果我在 Fortran 中进行以下复制

 arr(i1:i2) = u(1:n) 

其中SIZE(arr(i1:i2)) == SIZE(u(1:n)) 并且大小相对较大,例如 2M 双精度元素。

如果变量arr 是指向另一个可分配数组的指针别名。 Fortran 会使用堆栈或堆内存来处理复制分配吗?

如果它正在使用堆栈,是否有任何特定的原因选择。

如果不必在 Linux 终端上运行 ulimit -s unlimited,如何避免使用堆栈的编译器不会导致堆栈溢出?

【问题讨论】:

  • 如果它像鸭子一样走路 .... 没有足够的信息(即代码)来猜测使用堆栈空间的解释。
  • 如果数组是指针(而不是可分配的),编译器假定可能有重叠,并会使用一个临时数组。 IIRC,当前 ifort 版本默认动态分配数组临时,但如果您有旧版本,请尝试将 -heap-arrays 添加到编译中。
  • 如果变量是指针,那么编译器几乎肯定会使用堆栈进行复制。我认为默认是使用堆是不正确的——在版本 19 中它仍然默认使用堆栈。寻找 intel_fast_memcpy 不会告诉你任何有用的信息。
  • 您应该在问题中插入实际更完整的代码。 Variale 声明应该是绝对最低限度的。我不明白为什么人们投票而不是增加另一个接近投票。有问题的问题必须有minimal reproducible example
  • 对于提到的操作,fortran 是使用堆还是堆栈是一个相当开放的问题,并且已经回答了。我看到您自己已经回答了很多此类问题?

标签: segmentation-fault fortran intel-fortran


【解决方案1】:

如果变量是指针,那么编译器几乎肯定会使用堆栈来为副本创建临时文件,因为它必须假设可能存在重叠。它也可能不是简单的重叠,具有不连续的片段,因此以不同的顺序进行复制并不总是有效。

Fortran 的语义是赋值的右侧在左侧被更改之前被完全评估。除非编译器可以证明没有重叠(使用ALLOCATABLE 就足够了),否则它通常会使用堆栈临时来进行复制。 Intel Fortran 有一个选项-heap-arrays,告诉它在堆上分配这些临时值,避免堆栈溢出。

【讨论】:

    猜你喜欢
    • 2014-02-05
    • 1970-01-01
    • 2013-10-25
    • 2023-03-09
    • 2023-02-24
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 2015-08-07
    相关资源
    最近更新 更多