此程序在MacOSX Lion和ifort(IFORT)12.1.0 20111011上使用Illegal instruction: 4崩溃

program foo
      real, pointer :: a(:,:), b(:,:)
      allocate(a(5400, 5400))
      allocate(b(5400, 3600))
      a=1.0
      b(:, 1:3600) = a(:, 1:3600)

      print *, a
      print *, b

      deallocate(a)
      deallocate(b)

end program

相同的程序可用于gfortran。我没看到任何问题。有任何想法吗 ?在两个编译器中都可以展开副本并在各列上执行显式循环。

请注意,使用可分配而不是指针,我没有任何问题。

如果语句在模块内部或不在模块内部,则行为是相同的。
我在ifort(IFORT)12.1.3 20120130上确认了相同的行为。

显然,Linux和ifort 12.1.5不会发生任何问题

我试图通过以下链接选项来增加堆栈大小
ifort -Wl,-stack_size,0x40000000,-stack_addr,0xf0000000 test.f90
但我仍然遇到相同的错误。将ulimit -s增加到同样的问题。

编辑2:我进行了更多的调试,显然,数组拼接操作时会发生问题
      b(:, 1:3600) = a(:, 1:3600)

所涉及的值可疑地接近16M。

我正在比较产生的操作码,但是如果有一种方法可以看到一种更具交流性的中间代码形式,我将非常高兴。

最佳答案

您的程序是正确的(尽管如果您不需要重新指向指针,我希望将其分配给指针)。问题在于,默认情况下,ifort会将所有数组临时变量放置在堆栈上,无论它们的大小如何。似乎需要一个临时数组用于您在此处执行的复制操作。要解决ifort愚蠢的默认行为,请在编译时始终使用-heap-arrays标志。 IE。

ifort -o test test.f90 -heap-arrays 1600

-heap-arrays后面的数字是阈值,应在该阈值开始使用堆。对于低于此尺寸的尺寸,将使用堆栈。我在这里选择了一个很小的数字-您可能可以放心使用更高的数字。从理论上讲,堆栈数组的速度更快,但差异通常可以忽略不计。我希望intel可以解决此问题。每个其他编译器对此设置都有合理的默认值。

关于fortran - 使用ifort进行数组复制的程序崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12167549/

10-12 16:13