我正在使用 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 系统上的堆栈大小非常不同,在 Unix 系统上堆栈大小可以通过限制机制动态控制。
要增加 Windows 可执行文件的堆栈大小,您可以使用editbin.exe
来自 Microsoft 的命令行如下:
editbin /STACK:<size> yourexe.exe
或者向 GCC 提供以下选项:-Wl,--stack,<size in bytes>
, where <size in bytes>
是所需的堆栈大小(以字节为单位)。您应该将堆栈大小设置为至少足够大以适合整个数组(即8*NUMLOOPS
)以及局部变量之类的东西。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)