1

私は fortran と gfortran が初めてです。式の配列全体が並列で計算されることを学びましたが、計算はコンピューターの 1 つのコアでしか行われないことがわかりました。

次のコードを使用します。

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 によってリアルタイムで生成されたグラフを見ると、コアが 1 つしか機能していないことがわかります。行を計算に置き換えると

  C = matmul(A , B)

為に

  C = A * B

同じ動作が得られます。

私は何を間違っていますか?

4

3 に答える 3

2

gfortran からの matmult への呼び出しをマルチスレッドにしたい場合、最も簡単なのは、マルチスレッド サポートでコンパイルされた外部BLASパッケージにリンクすることです。候補には、OpenBlas (旧称 Goto Blas)、ATLAS 、または Intel の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

ここでは特に、リアルタイムがユーザー時間よりも短いことに注意してください。これは、複数のコアが使用されていることを示しています。

于 2013-07-02T12:33:00.640 に答える
2

GFortran/GCC にはいくつかの自動並列化機能があります。 http://gcc.gnu.org/wiki/AutoParInGCCを参照してください。多くの場合、それらはあまり良くないため、どの -ON 最適化レベルでも有効にされていません。-ftree-parallelize-loops=N を使用して特に選択する必要があります。ここで、N は使用するスレッドの数です。ただし、上記の例では、「A*B」のようなループは (十分に大きな配列の場合) メモリ帯域幅によって制約される可能性が高いため、コアを追加してもあまり役に立たない可能性があることに注意してください。さらに、MATMUL 組み込み関数は gfortran ランタイム ライブラリでの実装につながりますが、これは autopar オプションを使用してコンパイルされません (特にそのようにビルドした場合を除く)。

上記のサンプルコードをさらに助けることができるのは、実際に最適化をまったく有効にすることです。-O3 を指定すると、Gfortran は自動的にベクトル化を有効にします。これは、複数の CPU コアではありませんが、ループを並列化する方法と見なすこともできます。

于 2013-07-01T13:51:05.370 に答える
1

あなたが引用したコースの重要な文は、「配列の割り当てでは、個々の割り当ての暗黙の順序はなく、概念的には並行して実行される」だと思います。キーワードは「概念的に」です。配列式全体が実際に並列に実行されると言っているわけではありません。複数のコアが使用されるとは思わないでください。そのためには、OpenMP または MPI (Fortran 自体の外部) または Fortran 2008 の共配列を使用する必要があります。

編集: Fortran は、言語の一部として、Fortran 2008 の coarrays まで実際の並列実行を持っていませんでした。一部のコンパイラは並列化を提供する場合があり、一部の言語機能により、コンパイラは並列実行を簡単に実装できます (オプション)。私が Web 記事から引用した文は、あなたが引用した部分よりも現実をよく表しています。配列全体の式は、並列実行を要求することを意図していませんでした。これらはプログラマーにとって構文的に便利であり、言語をより高いレベルにし、do ループを記述せずに配列操作を単一のステートメントで表現できるようにします。いずれにせよ、ウェブ上の記事は決定的なものではありません。並列実行がないことを観察すると、どのステートメントが正しいかがわかります。Fortran 言語と矛盾しません。

于 2013-07-02T12:09:46.530 に答える