Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parallel processing 是否启用了gfortan全数组表达式?_Parallel Processing_Fortran_Gfortran - Fatal编程技术网

Parallel processing 是否启用了gfortan全数组表达式?

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

我对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)
为了

它产生同样的行为

我做错了什么?

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
特别注意,这里的实时性小于用户时间