6

金属板の表面の温度点を表す 2D マトリックスが与えられました。マトリックス (プレート) のエッジは 20 ℃ で一定に保たれ、事前に定義された 1 点には 100 ℃ の一定の熱源があります。他のすべてのグリッド ポイントは、最初は 50 ℃ に設定されています。

私の目標は、すべての内部グリッド ポイントを取得し、収束 (の変化反復間で 0.02 ℃ 未満)。

私の知る限り、グリッド ポイントを反復処理する順序は関係ありません。

私には、これは FortranFORALL構造を呼び出して並列化の楽しさを探求する絶好の機会のように思えます。

コードが実際に並列化されていることを確認するにはどうすればよいですか?

たとえば、シングル コアの PowerBook G4 でこれをコンパイルできますが、並列化による速度の向上は期待できません。しかし、デュアル コア AMD Opteron でコンパイルすると、FORALL コンストラクトを悪用できると思います。

あるいは、プログラムの効果的な並列化を測定する方法はありますか?

アップデート

MSB の質問に答えて、これは gfortran バージョン 4.4.0 を使用しています。gfortran は自動マルチスレッドをサポートしていますか?

FORALL コンストラクトが時代遅れになったことは注目に値します。おそらく、当時の自動ベクトル化です。

おそらくこれは別の質問に最適ですが、自動ベクトル化はどのように機能しますか? コンパイラは、純粋な関数またはサブルーチンのみがループで使用されていることを検出できますか?

4

3 に答える 3

7

FORALLは割り当て構造であり、ループ構造ではありません。FORALLのセマンティクスでは、FORALL内の各割り当ての右側(RHS)の式は、左側(LHS)に割り当てられる前に完全に評価されます。これは、RHSとLHSが重複する場合を含め、RHSでの操作がどれほど複雑であっても実行する必要があります。

ほとんどのコンパイラは、最適化が困難であり、一般的に使用されていないため、FORALLの最適化を重視しています。最も簡単な実装は、RHSに一時を割り当て、式を評価して一時に格納し、結果をLHSにコピーすることです。この一時的な割り当てと割り当て解除により、コードの実行が非常に遅くなる可能性があります。コンパイラがRHSを一時的に評価できる時期を自動的に判断することは非常に困難です。ほとんどのコンパイラはそうしようとはしません。ネストされたDOループは、分析と最適化がはるかに簡単であることがわかります。

一部のコンパイラでは、FORALLをOpenMPの「workshare」ディレクティブで囲み、OpenMPを有効にするために必要なフラグを使用してコンパイルすることで、RHSの評価を並列化できる場合があります。

!$omp parallel workshare
FORALL (i=,j=,...)
    <assignment>
END FORALL
!$omp end parallel

gfortran -fopenmp blah.f90 -o blah

RHSを並行して評価するために、準拠したOpenMP実装(少なくとも古いバージョンのgfortranを含む)は必要ないことに注意してください。実装がRHSをOpenMPの「単一」ディレクティブで囲まれているかのように評価することは許容されます。「ワークシェア」は、RHSによって割り当てられた一時的なものを排除しない可能性が高いことにも注意してください。これは、たとえばMacOSX上の古いバージョンのIBMFortranコンパイラの場合でした。

于 2010-09-21T19:40:12.480 に答える
6

インテル Fortran コンパイラーを使用する場合は、コマンドライン スイッチを使用して、コンパイラーの並列化/ベクトル化の詳細レベルをオン/上げることができます。このようにして、コンパイル/リンク中に次のように表示されます。

FORALL loop at line X in file Y has been vectorized

前回使用してから数年が経過していることは認めます。そのため、コンパイラ メッセージは実際には大きく異なって見えるかもしれませんが、それが基本的な考え方です。

于 2010-09-20T04:22:11.817 に答える
3

最良の方法は、計算のクロック時間を測定することです。並列コードの有無にかかわらず試してみてください。クロック時間が減少する場合、並列コードは機能しています。コード ブロックの前後で呼び出される Fortran 組み込みの system_clock は、クロック時間を提供します。組み込みの cpu_time は CPU 時間を提供します。これは、オーバーヘッドのためにコードがマルチスレッドで実行されると増加する可能性があります。

伝承は、FORALL が言語に導入されたときに考えられていたほど有用ではないということです。つまり、それは初期化構造のようなものです。コンパイラは、通常のループの最適化にも同様に優れています。

Fortran コンパイラは、OpenMP や MPI など、明示的に指定されていなくても真の並列処理を実装する能力が異なります。どのコンパイラを使用していますか?

自動マルチスレッドを実現するために、ifort を使用しました。手動で、OpenMP を使用しました。これらの両方を使用すると、並列化を使用して、または使用せずにプログラムをコンパイルし、違いを測定できます。

于 2010-09-05T23:10:02.503 に答える