使用gfortran

时间:2016-08-10 20:58:13

标签: parallel-processing fortran gfortran

我正在尝试加速一个非常冗长的程序,该程序最初不是为并行计算而设计的。因此,我正在尝试使用gfortran进行自动并行化。

我有以下测试程序,基本上只执行一些循环并测量执行时间:

program autoparallel

    implicit none

    integer                       :: N = 10000
    double precision, allocatable :: A(:, :), X(:), Y(:)

    integer                       :: i, j
    integer                       :: time_start, time_finish, time_rate

    call system_clock ( time_start, time_rate )

    allocate( A(N, N), X(N), Y(N) )

    do i=1, N
        do j=1, N
            A(i, j) = i * j
        end do
    end do

    do i=1, N
        X(i) = i
    end do

    do i=1, N
        Y(i) = 0.d0
    end do

    do i=1, N
        do j=1, N
            Y(i) = Y(i) + A(j, i) * X(j)
        end do
    end do

    call system_clock ( time_finish, time_rate )

    write(*,*) 'Elapsed time: ', (time_finish-time_start)/real(time_rate), ' seconds'

    write(*,*) Y(1), Y(N)

    deallocate(A, X, Y)

end program autoparallel

我用不同的编译器标志执行了五次:

gfortran test.f90
4.14799976      seconds
4.51900005      seconds
4.42399979      seconds
4.15600014      seconds
4.38000011      seconds

gfortran -floop-parallelize-all -ftree-parallelize-loops=2 autoparallel.f90
4.36899996      seconds
4.07499981      seconds
4.35599995      seconds
4.17899990      seconds
4.37500000      seconds

gfortran -floop-parallelize-all -ftree-parallelize-loops=4 autoparallel.f90
4.28399992      seconds
4.42600012      seconds
4.19999981      seconds
4.33199978      seconds
4.14499998      seconds

gfortran -O3 autoparallel.f90
3.63599992      seconds
3.63599992      seconds
3.79800010      seconds
3.55900002      seconds
3.59599996      seconds

gfortran -O3 -floop-parallelize-all -ftree-parallelize-loops=4 autoparallel.f90
3.09299994      seconds
3.08299994      seconds
3.46799994      seconds
3.00099993      seconds
3.00699997      seconds

gfortran -O3 -floop-nest-optimize autoparallel.f90
1.03100002      seconds
1.01800001      seconds
1.02300000      seconds
1.03600001      seconds
0.947000027      seconds

所以基本上执行时间与线程数一致。只有在优化之后,自动并行化才能启动。 我试图理解为什么会这样。

至少所有i - 循环都可以分布在多个线程上而无需任何优化。

那么这里究竟发生了什么?还有其他编译器标志可以用来进一步加速程序吗?什么标志会与我的并行化目标相冲突?

-floop-nest-optimize无法与-floop-parallelize-all一起使用。 错误:

isl_constraint.c:497: position out of bounds

1 个答案:

答案 0 :(得分:0)

我发现第三个循环通常通过OpenMP REDUCTION(或者ifort上的!DIR $ DO SIMD减少)得到改善。

USE OMPLIB
....
do i=1, N
    !$OMP DO SIMD REDUCTION(+:Y)
    do j=1, N
        Y(i) = Y(i) + A(j, i) * X(j)
    end do
end do

通过一些工作,也许Y(I)可以是PRIVATE,在I循环上并行。除非工作负载很高,否则在这些简单的情况下,对于I循环并行化很少有很多改进。

YRMV