无效的内存访问fortran检查员

时间:2013-01-23 10:00:27

标签: arrays memory fortran inspector

如果我使用数组运行我的fortran程序(查看代码),我的计算值会出错。如果我使用intel检查器(-mi3),它会告诉我每次在程序中使用一个大数组时存在“无效内存访问”的内存问题,并且/ lib64 / ld-linux-x86-中存在错误64.so.2。 首先,我认为我没有足够的内存空间,但在具有16 GB内存的64位机器上有足够的内存空间(:free -m~14 GB)。 如果我估计我的程序的内存大小,大约4 GB就足够了。当我的程序运行时,已用内存从0%增加到~20%并停在那里直到程序“正常”终止。所以我觉得我有足够的内存空间。对于小阵列(例如nemax = 3 000 000),我在intel检查员中获得了正确的计算值并且没有错误。我还检查了数组,并检查了全部标志。 我使用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 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

除了其他优秀建议之外,我建议尽可能多地打开调试选项进行编译,包括运行时错误检查。编译器会向您发出有关可能导致错误的错误做法的警告,并会发现其他错误。不良做法包括未声明或未初始化的变量。我建议不使用隐式类型并声明每个变量。使用运行时下标检查,编译器将告诉您何时下标超出数组边界...比无效内存访问更容易理解的错误。使用intel 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在运行时找到一个未经传输的变量。这导致程序在数组末尾运行并访问无效内存。

答案 2 :(得分:1)

除了其他建议之外,您还应该确保在shell中没有达到默认的堆栈大小限制。静态数组通常在堆栈上创建,BASH中的默认堆栈大小为8Mb。如果您的阵列大于该阵列,则最终会导致访问冲突。您可以通过设置

覆盖此限制
ulimit -s unlimited
在BASH中

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

答案 3 :(得分:-2)

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