我有一个很大的Fortran-90
序列代码(所以我最好需要一个通用的方法来处理我的问题而不是代码的多个特定更改),我希望使用OpenMP
的子句来并行。我想尝试粗粒度并行化,因为我的代码的主体看起来像:
Program Example
Serial code here
DO I=is,ie
DO J=js,je
Main body of calculations
ENDDO
ENDDO
Serial code here
End Program Example
(1)准备串行代码进行并行化的首选步骤是什么?
(2)由于-openmp
将automatic
设置为默认值(来自编译器手册),因此它将本地标量和数组移动到堆栈。我先尝试使用-auto
来运行代码(编译器标志为:'ifort -g -O3 -mcmodel=medium -xHost -auto -no-prec-div -fpconstant -fp-model precise -fpe0 -traceback -ftrapuv -convert big_endian -gen-interfaces -warn interfaces -I/usr/local/netcdf/4.3.3.1/include -L/usr/local/netcdf/4.3.3.1/lib -lnetcdff -lnetcdf'
)并获得SIGFPE
:Program received signal SIGFPE, Arithmetic exception.
0x00002aaaab445885 in pow.L () from /usr/local/netcdf/4.3.3.1/lib/libnetcdf.so.7
(3)我也试过了-openmp
(序列码中没有任何条款!),并且SIGFPE
也在同一点上。
如何明智地使用编译器标志(并且可能略微修改我的代码)的任何见解/想法将非常感激。
答案 0 :(得分:0)
正如其他人所指出的那样,很难帮助解决代码中的特定SIGFPE错误,特别是从给出的信息中。 SIGFPE建议算术错误可能与多线程完全无关。我建议检查它出现的行并查找除以零等。您也可以删除-fpe0标志以避免此错误(不推荐)。对于openMP,这是以您拥有的形式运行多个线程的最简单示例,
Program Example
implicit none
integer :: I, J
integer :: is, ie, js, je
integer :: nthreads, OMP_GET_NUM_THREADS
integer :: ithread, omp_get_thread_num
!Serial code here
!$OMP PARALLEL
nthreads = OMP_GET_NUM_THREADS()
ithread = omp_get_thread_num()
is = 1; ie = 10
js = 1; je = 5
DO I=is,ie
DO J=js,je
!Main body of calculations
print'(4(a,i5))', 'loop I= ', I, &
' J= ', J, &
' on thread ', ithread+1, &
' of ', nthreads
ENDDO
ENDDO
!$OMP END PARALLEL
!Serial code here
end program
可以使用ifort -openmp script.f90编译。希望这会有所帮助。