Fortran 90 中模块中定义的数组(例如 a(10000))的存储位置在哪里?是否放入栈中?

发布于 2025-01-13 06:23:56 字数 595 浏览 1 评论 0原文

我的 Fortran 90 程序面临堆栈溢出问题。我把所有参数都放在模块中,运行大型示例时出现段错误,这让我很困惑 TAT。我编写了一个小程序来验证我对问题可能出在哪里的假设。我发现了一些有趣的现象,想问一下它们的原理是什么。

  1. 我在模块中放置了一个非常大的数组(等等REAL a(10000000))。当我在子程序中使用它时,不会出现段错误。因此我想知道数组的存储在哪里?

  2. 我在子例程A中分配了一个非常大的数组(等等allocate(a(10000000))),并将其传输到另一个子例程B< /代码>。在B中,我将其定义为a(10000000),并且不会出现段错误。因此我想知道可分配数组的两个子例程之间传输什么?

  3. 对于我自己的复杂程序,我已经检查了几次我在模块中分配了每个数组,但是当示例变大时,仍然会发生段错误。我只是想知道我是否遗漏了一些会影响堆栈使用的东西。

现在,我不知道在哪里检查 TAT,所以有人可以给我一些调试堆栈溢出段错误的见解吗?我将非常感激!

I am facing problems of stack overflow for my Fortran 90 program. I put all the parameters in module, and i got segment fault when running big examples, which makes me confused TAT. I have written a small program to verify my assumption of where the problem might be. I got some interesting phenomenon, and want to ask what is the principle of them.

  1. I put an extremely large array in a module (etc. REAL a(10000000)). When I use it in the subroutine, there won't be segment fault. Thus I am wondering where the storage of the array is?

  2. I allocate an extremely large array (etc. allocate(a(10000000))) in a subroutine A, and transmit it into another subroutine B. In B, I define it as a(10000000), and there won't be segment fault. Thus I am wondering what is transmitted between two subroutine of an allocatable array?

  3. For my own complicated program, I have checked several times that I allocate every arrays in module, but the segment fault is still happened when example is getting large. I just want to know if there is something I'm missing which will influence the usage of stack.

Now, I have no idea where to check TAT, so is there anybody can give me some insight of debugging the segment fault with stack overflow? I will appreciate so much for that!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长不大的小祸害 2025-01-20 06:23:56

我能够使用 Intel Fortran(oneAPI HPC 套件,ifort)复制该问题。为了缓解这个问题,我在大小超过 1000 kb 时设置了堆数组。

fig1

如果没有此设置,以下测试代码

program Console2
use LU_MODULE
    
integer, parameter :: n = 359
real(wp) :: A(n,n), LU(n,n), b(n), x(n), delta
integer :: indx(n), d, ierr

call RANDOM_SEED()
call RANDOM_NUMBER(A)
call RANDOM_NUMBER(b)

A = 3*(A + eye(n))   ! Line 18, where error occus
print *, 'n=', n, ' mem=', sizeof(A)/1024, 'kb'

...

n>=359 时失败。

forrtl: severe (170): Program Exception - stack overflow
Image              PC                Routine            Line        Source
FortranConsole2.e  00007FF7F363A727  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363509A  MAIN__                     18  program.f90
FortranConsole2.e  00007FF7F3637E6E  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363AA59  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363A97E  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363A83E  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363AACE  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FFC336A7034  Unknown               Unknown  Unknown
ntdll.dll          00007FFC33B42651  Unknown               Unknown  Unknown

但启用设置后我得到了预期的输出

 n=         359  mem=                  1006 kb
 ...

I am able to replicate the problem with Intel Fortran (oneAPI HPC kit, ifort). To mitigate the problem I setup heap arrays when over 1000 kb in size.

fig1

The following test code

program Console2
use LU_MODULE
    
integer, parameter :: n = 359
real(wp) :: A(n,n), LU(n,n), b(n), x(n), delta
integer :: indx(n), d, ierr

call RANDOM_SEED()
call RANDOM_NUMBER(A)
call RANDOM_NUMBER(b)

A = 3*(A + eye(n))   ! Line 18, where error occus
print *, 'n=', n, ' mem=', sizeof(A)/1024, 'kb'

...

Fails when n>=359 without this setting.

forrtl: severe (170): Program Exception - stack overflow
Image              PC                Routine            Line        Source
FortranConsole2.e  00007FF7F363A727  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363509A  MAIN__                     18  program.f90
FortranConsole2.e  00007FF7F3637E6E  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363AA59  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363A97E  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363A83E  Unknown               Unknown  Unknown
FortranConsole2.e  00007FF7F363AACE  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FFC336A7034  Unknown               Unknown  Unknown
ntdll.dll          00007FFC33B42651  Unknown               Unknown  Unknown

but with the setting enabled I get the expected output

 n=         359  mem=                  1006 kb
 ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文