0

如果我使用数组运行我的 fortran 程序(查看代码),我会得到错误的计算值。如果我使用英特尔检查器 (-mi3),它会告诉我每次在程序中使用一个大数组时都会出现内存问题“无效内存访问”,并且 /lib64/ld-linux-x86- 中也会出现错误64.so.2。首先,我认为我没有足够的内存空间,但是在我的 64 位机器上 16 GB 内存有足够的内存空间(:free -m ~14 GB)。如果我估计我的程序的内存大小,大约 4 GB 应该足够了。当我的程序运行时,使用的内存从 0% 增加到 ~20% 并停在那里直到程序“正常”终止。所以我认为我有足够的内存空间。对于小型数组(例如 nemax=3 000 000),我在 intel 检查器中获得了正确的计算值并且没有错误。我还用 flag check all 检查了数组。我用 ifort -mcmodel=medium -shared-intel -o test test.f90 编译程序。我不知道我还能做些什么来解决这些内存访问错误?有人有想法吗??谢谢你的帮助!

  module lz_data

  integer,parameter :: maxsite=16   
  integer,parameter :: nmax =6000000 
  integer,parameter :: nemax=300000000

  real*8,save :: diag(nmax)        

  real*8,save  :: werte(nemax)              !Here are the only large arrays
  integer,save :: izeile(nemax)
  integer,save :: ispalt(nemax)

  integer,save :: nentry

  end module lz_data

  prgram test
  use lz_data

  implicit real*8 (a-h,o-z)
  real*8 umat(maxsite,maxsite)
  logical lav(nmax,maxsite) 
  logical lbv(nmax,maxsite) 

  ...

  do is=1,ns
    diag(is)=0.0d0    ! HERE the debugging tool says invalid memory access 
    do i=1,msite
      do j=1,msite
        if (lav(is,i).and.lbv(is,j)) diag(is)=diag(is)+umat(i,j) ! invalid memory access
      enddo
    enddo
  enddo
4

4 回答 4

1

看起来您遇到了一些静态数组大小限制。mcmodel=medium “应该”对此有所帮助,但显然没有。你可以用可分配数组替换你的大静态数组,看看是否有帮助。

哦,就像 High Performane Mark 所说,使用隐式无,确保初始化所有变量,并提供一个自包含的示例代码。

于 2013-01-23T11:02:51.567 回答
1

除了其他出色的建议之外,我建议编译时尽可能多地打开调试选项,包括运行时错误检查。编译器会针对可能导致错误的不良做法向您发出警告,并会发现其他错误。不良做法包括未声明或未初始化的变量。我建议不要使用隐式类型并声明每个变量。通过运行时下标检查,当下标超出数组边界时,编译器会告诉您……这是一个比无效内存访问更容易理解的错误。使用英特尔 ifort 尝试:-O2 -stand f03 -assume realloc_lhs -check all -traceback -warn all -fstack-protector -assume protect_parens -implicitnone

在编辑您的代码示例以便使用这些选项强制执行的规则进行干净编译后,运行会给出错误消息:

forrtl: severe (193): Run-Time Check Failure. The variable '_test_$NS' is being used without being defined

即,ifort 在运行时发现一个未初始化的变量。这导致程序在数组末尾运行并访问无效内存。

于 2013-01-23T11:37:36.663 回答
1

除了其他建议之外,您还应该确保您没有受到 shell 中默认堆栈大小限制的影响。静态数组通常是在栈上创建的,BASH 中默认的栈大小是 8Mb。如果您有比这更大的数组,您最终会遇到访问冲突。您可以通过设置覆盖此限制

ulimit -s unlimited

在 BASH 中,因此您的堆栈大小仅受系统中可用内存的限制。

于 2013-01-23T12:34:22.087 回答
-2

谢谢你的帮助!我已经设置了 ulimit -s unlimited 或 10 GB。我知道使用隐式不太好,但是对于较小的系统,我的程序运行得非常好,那么为什么使用隐式会出错。我想使用可分配数组而不是大静态数组,但在我的情况下它没有意义,因为大数组 werte 的值的计算与数组的范围相关联。所以我必须浪费一点(!)内存来预测我的静态数组的足够维度。在我的情况下,预测维度并不复杂,我绝对(100%)确定计算出的数组适合静态数组。我什至用 -check all 标志检查了它。我可以使用 diag(nmax) 数组创建一个可分配数组,所以我会检查这个,

于 2013-01-25T10:39:59.703 回答