fortran - 大型阵列导致 OpenMP 崩溃

标签 fortran openmp fortran90 gfortran

我正在使用 Fortran 和 OpenMP,但是当我尝试在存在大型数组时使用 OpenMP 并行化循环时,我一直遇到问题。例如下面的代码:

PROGRAM main
IMPLICIT NONE   
INTEGER, PARAMETER :: NUMLOOPS = 300000
REAL(8) :: TESTMAT(NUMLOOPS)
INTEGER :: i,j

!$OMP PARALLEL SHARED(TESTMAT)
!$OMP DO
DO i=1,NUMLOOPS         
    TESTMAT(i) = i
END DO
!$OMP END DO
!$OMP END PARALLEL

write(*,*) SUM(TESTMAT)/(NUMLOOPS)

END PROGRAM main

使用这个 Makefile 编译:

.SUFFIXES: .f90

F90 = gfortran
FFLAGS_PFM = -ffree-form -ffree-line-length-none -fopenmp
LIB = -llapack
OBJ90 = main.o 

main: $(OBJ90)
    $(F90) $(FFLAGS_PFM) -o $@ $(LIB) $(OBJ90)

${OBJ90}: %.o: %.f90
    $(F90) $(FFLAGS_PFM) $(LIB) -c -o $@ $<

在 Windows 机器上崩溃,使用 gfortran 编译。但是,如果我将 NUMLOOPS 值更改为小于 260000 左右的值,程序运行正常。同样,大约 1000x1000 的矩阵会崩溃(任何超过 500x500 的矩阵实际上都不起作用)。因此,似乎在使用 OpenMP 时允许最大数组大小?我还没有遇到过这种情况。我在多台 Windows 机器上试过,结果相同,但是都使用相同的配置,例如带有 gfortran 编译器的 Windows 7。代码总是可以毫无问题地编译,但在运行时会崩溃。

最佳答案

指定 -fopenmp在 GNU Fortran 中表示 -frecursive这意味着所有局部变量(甚至是大数组)都是自动的(即分配在堆栈上)。在 Windows 上,堆栈大小在 PE 可执行头文件中是固定的,并且必须在链接阶段指定,这与 Unix 系统非常不同,后者可以通过限制机制动态控制。

要增加 Windows 可执行文件的堆栈大小,您可以使用 editbin.exe来自 Microsoft,命令行如下:

editbin /STACK:<size> yourexe.exe

或向 GCC 提供以下选项:-Wl,--stack,<size in bytes> , 其中<size in bytes>是以字节为单位的所需堆栈大小。您应该将堆栈大小设置为至少足以容纳整个数组(即 8*NUMLOOPS )以及局部变量和其他内容。

关于fortran - 大型阵列导致 OpenMP 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10269836/

相关文章:

performance - Fortran:32 位/64 位性能可移植性

linux - Bin 数据在 AIX 和 Linux 中的读取方式不同

java - 正在寻找计算大型矩阵并输出它们的最快方法?

c++ - 多平台多处理?

visual-studio - Qt5、Visual Studio 2012 Express 和 OpenMp。如何?

Cmake : file is not copying

c++ - 升级 Visual Studio 后 Fortran DLL 出现异常

c++ - 在 Mac OS X Lion 上使用 OpenMP 编译失败(memcpy 和 SSE 内在函数)

emacs - 我可以使用固定格式的 emacs f90-mode 吗?

fortran - 使用 Fortran 从文件中提取指定行