我是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
它会产生相同的行为。
我做错了什么?
答案 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语言并不矛盾。