Parallel processing 是否启用了gfortan全数组表达式?
我对fortran和gfortran都是新手。我了解到整个表达式数组是并行计算的,但我发现计算只在我的计算机的一个核心中进行 我使用以下代码:Parallel processing 是否启用了gfortan全数组表达式?,parallel-processing,fortran,gfortran,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 precisio
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)
为了
它产生同样的行为
我做错了什么?GFortran/GCC确实有一些自动并行功能,请参阅。它们通常不是很好,因此在任何-ON优化级别上都没有启用它们,您必须特别使用-ftree parallelize loops=N来选择它,其中N是您想要使用的线程数。但是请注意,在上面的示例中,像“a*B”这样的循环可能会受到内存带宽的限制(对于足够大的阵列),因此添加内核可能不会有多大帮助。此外,MATMUL内在函数导致gfortran运行时库中的实现,该库不使用autopar选项编译(除非您专门以这种方式构建)
上面的示例代码能够提供更多帮助的是实际启用任何优化。使用-O3 Gfortran可以自动启用矢量化,这也可以看作是一种并行化循环的方法,尽管不能跨越多个cpu核 GFortran/GCC确实有一些自动并行功能,请参阅。它们通常不是很好,因此在任何-ON优化级别上都没有启用它们,您必须特别使用-ftree parallelize loops=N来选择它,其中N是您想要使用的线程数。但是请注意,在上面的示例中,像“a*B”这样的循环可能会受到内存带宽的限制(对于足够大的阵列),因此添加内核可能不会有多大帮助。此外,MATMUL内在函数导致gfortran运行时库中的实现,该库不使用autopar选项编译(除非您专门以这种方式构建)
上面的示例代码能够提供更多帮助的是实际启用任何优化。使用-O3 Gfortran可以自动启用矢量化,这也可以看作是一种并行化循环的方法,尽管不能跨越多个cpu核 我认为您所引用的课程中的一个关键句子是“数组赋值没有隐含的单个赋值顺序,它们在概念上是并行执行的。”关键词是“概念上”。这并不是说整个数组表达式实际上是并行执行的;您不应该期望使用多个核心。为此,您需要使用OpenMP或MPI(Fortran本身之外)或Fortran 2008的coarray
编辑:作为语言的一部分,Fortran在Fortran 2008的coarray之前没有实际的并行执行。有些编译器可能以其他方式提供并行化,有些语言特性使编译器更容易实现并行执行(可选)。我从网络文章中引用的句子比你引用的部分更能说明现实。整个数组表达式不需要并行执行;它们为程序员提供了语法上的便利,使语言更高级,因此数组操作可以用单个语句表示,而无需编写do循环。无论如何,网络上的任何文章都不是决定性的。您对缺乏并行执行的观察表明了哪种说法是正确的。它与Fortran语言并不矛盾 我认为您所引用的课程中的一个关键句子是“数组赋值没有隐含的单个赋值顺序,它们在概念上是并行执行的。”关键词是“概念上”。这并不是说整个数组表达式实际上是并行执行的;您不应该期望使用多个核心。为此,您需要使用OpenMP或MPI(Fortran本身之外)或Fortran 2008的coarray
编辑:作为语言的一部分,Fortran在Fortran 2008的coarray之前没有实际的并行执行。有些编译器可能以其他方式提供并行化,有些语言特性使编译器更容易实现并行执行(可选)。我从网络文章中引用的句子比你引用的部分更能说明现实。整个数组表达式不需要并行执行;它们为程序员提供了语法上的便利,使语言更高级,因此数组操作可以用单个语句表示,而无需编写do循环。无论如何,网络上的任何文章都不是决定性的。您对缺乏并行执行的观察表明了哪种说法是正确的。它与Fortran语言并不矛盾 如果您希望从gfortran对matmult的调用是多线程的,最简单的方法是链接到使用多线程支持编译的外部包。候选产品包括(née Goto Blas)或商业软件包,如英特尔、AMD或苹果的加速框架 例如,对于这个简单的例子:
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
这里要特别注意的是,实时时间小于用户时间,这表明正在使用多个内核。如果您希望从gfortran调用matmult是多线程的,最简单的方法是链接到使用多线程支持编译的外部包。候选产品包括(née Goto Blas)或商业软件包,如英特尔、AMD或苹果的加速框架 例如,对于这个简单的例子:
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
特别注意,这里的实时性小于用户时间