我正在使用 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/