12

F# を使用して格子ボルツマン (流体力学) コードを開発しています。現在、24 コア、128 GB メモリのサーバーでコードをテストしています。このコードは基本的に、時間発展のための 1 つの主要な再帰関数と、3D 次元空間反復のための System.Threading.Tasks.Parallel.For ループ内で構成されます。3D スペースは 500x500x500 の大きさで、1 つのタイム サイクルが永遠に続きます :)。

let rec timeIterate time =
  // Time consuming for loop
  System.Threading.Tasks.Parallel.For(...)

サーバーは 24 個のコアすべてを使用する、つまり 100% 使用すると予想します。私が観察したのは、1% から 30% の使用率です。

そして私の質問は次のとおりです。

  1. F# は、そのようなサーバーでの HPC 計算に適したツールですか?
  2. 実際の問題に CPU を 100% まで使用することは現実的ですか?
  3. ハイスピードアップするにはどうすればいいですか?すべてが 1 つの大きな並列 for ループにあるので、それがすべて私がすべきことだと思います...
  4. F# が適切な言語でない場合、どの言語ですか?

ご提案ありがとうございます。

編集: 誰かが興味を持っている場合は、喜んでコードを共有します。

EDIT2 :コードの削除されたバージョンは次のとおりです: http://dl.dropbox.com/u/4571/LBM.zip

起動ファイルは ShearFlow.fs で、ファイルの一番下には

let rec mainLoop (fA: FArrayO) (mR: MacroResult) time =
  let a = LBM.Lbm.lbm lt pA getViscosity force g (fA, mR)
4

7 に答える 7

5

1. F# は、そのようなサーバーでの HPC 計算に適したツールですか?

It (F#) は、言語として、並列で適切に機能するコードを促進できます。これの少なくとも一部は、状態の可変性と高次関数の削減です。これはできますが、意志ではありません。ただし、HPC には、多くの特殊なプログラミング言語/コンパイラ、および/または負荷分散の方法 (共有ユニファイド メモリや分散マイクロカーネルなど) があります。F# は単なる汎用プログラミング言語です。さまざまな手法にアクセスできる場合とできない場合があります (たとえば、バインディングが存在する場合と存在しない場合があります)。(これは、非分散並列コンピューティングにも当てはまります。)

2. 実際の問題に CPU を 100% まで使用することは現実的ですか?

それは、制限要因が何であるかによって異なります。している友人と話す5k+100,000 以上のコア HPC の研究開発では、通常、データの交換アイドル時間が制限要因になります (もちろん、これははるかに高い n :-) ため、IO 削減 (効率または異なるアルゴリズム) の小さな改善でさえ、大幅な改善につながる可能性があります。ます。同じマシン上の CPU/キャッシュ間で単純にデータを移動するコストを忘れないでください! そしてもちろん、常に遅いディスク IO...

3. ハイスピードアップするにはどうすればいいですか?すべてが 1 つの大きな並列 for ループにあるので、それがすべて私がすべきことだと思います...

遅い部分がどこにあるかを見つけて、それを修正します:-) たとえば、プロファイル分析を実行します。まったく異なるアルゴリズムまたはアプローチを使用する必要がある場合があることに注意してください。

4 . F# が適切な言語でない場合、どの言語ですか?

私はそれについて議論しているわけではありませんが、私の博士号の友人はCharm++を使用/作業しています: これは分散並列コンピューティングに非常に焦点を当てた言語です (問題の環境ではありませんが、私は主張しようとしています :-) -- F# は試行しますまともな汎用言語であること。

于 2010-11-04T20:44:13.543 に答える
4

F# は、他の言語と同様に優れている必要があります。パフォーマンスを決定するのは、言語自体よりもコードの書き方です。

計算が CPU バウンドの場合、少なくとも 90% の範囲で 100% に近づくことができるはずです。

ここで 100% の CPU が得られない理由はいくつか考えられます。

  1. 計算は I/O バウンドである可能性があります (for ループでファイルまたはネットワーク操作を行いますか?)
  2. 多くのロックなどの同期の問題があります (結果を「コミット」する場所を含め、スレッド間で状態を共有していますか?)
于 2010-11-04T13:08:01.700 に答える
3

F# は、そのようなサーバーでの HPC 計算に適したツールですか?

私は F# についてあまり知りませんが、F# は非常に適していると思います。適切なツールがすべて揃っており、高度な並列実行に適した関数型言語です。

実際の問題に CPU を 100% まで使用することは現実的ですか?

はい、またはほとんどです。しかし実際には、24 個のコアがある場合、アプリケーションは CPU パワーの 2400% を使用する必要があります。少なくとも、通常はそのように表示されます。使用率が 30% である場合、シングルコアで実行されており、そのコアを使用していない可能性があります。

ハイスピードアップするにはどうすればいいですか?すべてが 1 つの大きな並列 for ループにあるので、それがすべて私がすべきことだと思います...

さて、あなたはあなたのコードを示していませんでした。コード内の何かが並列実行を妨げているとしか思えません。

または (1% から 30% の CPU 使用率がそれを示しています)、問題は実際には計算限界ではなく、計算は常にセカンダリ メモリなどの他のリソースを待機しています。これは必ずしも問題に依存するわけではありません。結局のところ、流体力学計算に縛られた問題なのです! –しかし、むしろあなたの特定の実装に。これまでのところ、多くの点でリソースの競合が指摘されています。

于 2010-11-04T13:06:35.397 に答える
2
  1. F# は、Fortran、C、および C++ が支配する HPC の主流にはまだなっていないと思いますが、F# を避けるべき特別な理由は見当たりません。

  2. いいえ、そうではありません。遅かれ早かれ、すべて (疑わしい主張) の HPC コードはメモリ帯域幅が制限されるようになります。CPU は、RAM が読み込んで保存するよりもはるかに高速に数値を処理できます。長時間の計算では、CPU が実行できる理論上の最大数の FLOP の 10% をうまく使用しています。

  3. あなたの構成について具体的なアドバイスを提供できるほど F# についてよく知っているわけではありません (私は HPC Fortran プログラマーの 1 人です)。しかし、一般的には、適切な負荷分散 (つまり、すべてのコアが同じ量の作業を行う)、メモリ階層の効率的かつ効果的な使用 (言語が「より高いレベル」になるにつれて難しくなる傾向があるため、困難になります) を確保する必要があります。プロセスを低レベルで管理するため)、最善の方法は、最適なアルゴリズムを選択することです。最良の並列アルゴリズムは、並列化された最良のシリアル アルゴリズムであるとは限りません。最良の機能 (実装) アルゴリズムは、最良の (命令型実装) アルゴリズムではない可能性があると思います。

  4. フォートラン。

于 2010-11-04T13:09:35.350 に答える
1

スレッド プールには、さまざまな状況に応じてスレッドの最大数があります。

MSDNから:

スレッド プール スレッドの最大数

スレッド プールのキューに入れることができる操作の数は、使用可能な > メモリによってのみ制限されます。ただし、スレッド プールは、プロセスで同時にアクティブにできるスレッドの数を制限します。.NET Framework バージョン 4 以降、プロセスのスレッド プールの既定のサイズは、仮想アドレス > スペースのサイズなど、いくつかの要因によって異なります。プロセスは、GetMaxThreads メソッドを呼び出して、スレッドの数を決定できます。

GetMaxThreads および SetMaxThreads メソッドを使用して、スレッドの最大数を制御できます。

また、必要に応じて MinThreads を上げてみてください。システムのコア数が原因で、スレッドプール最適化アルゴリズムが無効になっている可能性がありますか? 試すだけの価値があります。

繰り返しますが、MSDNから:

スレッド プールは、各カテゴリで指定された最小値に達するまで、オンデマンドで新しいワーカー スレッドまたは I/O 完了スレッドを提供します。GetMinThreads メソッドを使用して、これらの最小値を取得できます。

最小値に達すると、スレッド プールは追加のスレッドを作成するか、いくつかのタスクが完了するまで待機することができます。.NET Framework 4 以降、スレッド プールは、単位時間あたりに完了するタスクの数として定義されるスループットを最適化するために、ワーカー スレッドを作成および破棄します。スレッドが少なすぎると、使用可能なリソースを最適に使用できない可能性があり、スレッドが多すぎると、リソースの競合が増える可能性があります。

于 2010-11-04T13:35:47.840 に答える
1

関数型プログラミングは、高レベルの抽象化に焦点を当てています。つまり、一般的なプログラミング パターンを抽象化し、それらを一般的に再利用可能にします。ハイ パフォーマンス コンピューティングとは、物事を並行して実行すること、異なるスレッド間のビットについて考えること、キャッシュ ヒット率を高くするためのデータの局所性について考えることです。これらは 2 つの異なる方向です。

今日では、人々は FP をハイ パフォーマンス コンピューティングを含むすべての並列処理の特効薬と考える傾向があります。番号。それ以外の場合は、高性能の会議で公開された多くの FP 論文を目にすることになります。実はかなり少ない。

あなたが今使っているのは、C#/F#/VB の .Net ライブラリである Task Parallel ライブラリです。F# 固有ではありません。それ自体はC#で書かれていると思います。

これを念頭に置いて、あなたの質問に戻りましょう。100% の CPU を使用できないのはなぜですか? スキルは、ボトルネックが F# とあまり関係がないことを見つけるのに役立ちます。プログラムのプロファイリングを行い、一部のスレッドが他のスレッドの終了を待っているかどうかを確認します (続行するには Paralle.For ですべての計算を終了する必要があります)。

于 2010-11-05T01:29:39.510 に答える
0

Visual Studio に含まれているスレッド分析ツ​​ール (パフォーマンス ウィザードのコンカレンシー プロファイラー オプションを使用) を使用してみましたか?

于 2010-11-04T13:12:16.833 に答える