是否启用了gfortan整个数组表达式?

时间:2013-07-01 13:20:57

标签: parallel-processing fortran gfortran

我是fortran和gfortran的新手。我了解到整个表达式数组是并行计算的,但我发现计算只发生在我计算机的一个核心中。

我使用以下代码:

program prueba_matrices

 implicit none

 integer, parameter                             :: num = 5000
 double precision, dimension(1:num,1:num)       :: A, B, C
 double precision, dimension (num*num)          :: temp
 integer                               :: i

 temp = (/ (i/2.0, i=1,num*num) /)
 A = reshape(temp, (/ num, num/) )
 B = reshape(temp, (/ num, num/) )
 C = matmul(A , B)

end program prueba_matrices

我这样写:

gfortran prueba_matrices.f03 -o prueba_gfortran

而且,观看gnome-system-monitor实时生成的图表,我可以看到只有一个核心工作。如果我用计算替换该行

  C = matmul(A , B)

  C = A * B

它会产生相同的行为。

我做错了什么?

3 个答案:

答案 0 :(得分:2)

GFortran / GCC确实有一些自动并行化功能,请参阅http://gcc.gnu.org/wiki/AutoParInGCC。它们通常不那么好,因此它们不能在任何-ON优化级别启用,您必须使用-ftree-parallelize-loops = N专门选择它,其中N是您要使用的线程数。但请注意,在上面的示例中,像“A * B”这样的循环很可能受到内存带宽的限制(对于足够大的阵列),因此添加内核可能没那么多。此外,MATMUL内在函数导致gfortran运行时库中的实现,该库未使用autopar选项进行编译(除非您专门以这种方式构建它)。

有什么可以帮助您的示例代码更多地实际启用任何优化。使用-O3 Gfortran可以自动启用矢量化,这可以看作是一种并行化循环的方法,尽管不是几个cpu核心。

答案 1 :(得分:2)

如果您希望从gfortran调用matmult为多线程,最简单的方法是链接到已使用多线程支持编译的外部BLAS包。考生包括OpenBlas(néeGotoBlas),ATLAS或商业软件包,如英特尔MKL,AMD ACML或Apple的加速框架。

例如,对于这个简单的例子:

program timematmult

  real, allocatable, dimension(:,:) :: A, B, C
  integer, parameter :: N = 2048

  allocate( A(N,N) )
  allocate( B(N,N) )
  allocate( C(N,N) )

  call random_seed
  call random_number(A)
  call random_number(B)

  C = matmul(A,B)

  print *, C(1,1)

  deallocate(C)
  deallocate(B)
  deallocate(A)

end program timematmult

以matmul为基础:

$ gfortran -o matmult matmult.f90
$ time ./matmult
   514.38751

real    0m6.518s
user    0m6.374s
sys     0m0.021s

以及多线程的gotoblas库:

$ gfortran -o matmult matmult.f90 -fexternal-blas -lgoto2
$ time ./matmult
   514.38696

real    0m0.564s
user    0m2.202s
sys     0m0.964s

此处特别注意实时时间小于用户时间,表示正在使用多个核心。

答案 2 :(得分:1)

我认为你所引用的课程中的一个关键句子是“对于数组赋值,没有任何隐含的个别作业顺序,它们是在概念上并行执行的。”关键词是“概念”。并不是说整个数组表达式实际上是并行执行的;你不应该期望使用多个核心。为此,您需要使用OpenMP或MPI(Fortran本身之外)或Fortran 2008的阵营。

编辑:作为语言的一部分,Fortran没有实际的并行执行,直到Fortran 2008的阵营。有些编译器可能会提供并行化,而某些语言特性使编译器更容易实现并行执行(可选)。我从网络文章中引用的句子更好地陈述了现实,而不是你引用的部分。全数组表达式并不是要求并行执行;它们对程序员来说是一种语法上的便利,使语言更高级,因此数组操作可以用单个语句表示,而无需编写do循环。无论如何,网上没有文章是确定的。您对缺少并行执行的观察表明哪种说法是正确的。它与Fortran语言并不矛盾。