2012-01-24 11 views
2

大規模なネットワークの視覚化を高速化するためにOpenCLベースのパーティクルシステムを作成しています。本質的に、これはフェーズ1が各粒子(典型的なn体問題)に負の重力を適用するので、それらはすべて反発し、その後フェーズ2は粒子間のエッジ(またはバネ)に基づいて粒子を引き付ける2段階問題です。OpenCLパーティクルシステムでの浮動小数点精度の不足の扱い

重力アルゴリズムを繰り返し実行するたびに、フロートのペアとして表される各パーティクルの位置は、互いのパーティクル(古典物理モデル、ドラッグなし、単純なまま)までの距離に影響されます。一つは重力のアプリケーションはX及びY軸の両方を横切る対称性をもたらすはずである粒子の完全に間隔をあけ正方形アレイを有する状況では

。これは、重力アプリケーションの開始時に当てはまりますが、時間の経過とともに、多くの浮動小数点数を加算する際の精度の欠如は、不均一な偏差をもたらします。これは、順にn体系全体を伝播し、対称性の損失が生じる。これを回避する

1つの簡単な方法は、倍精度数をサポートしていない私のMacBook Proに倍精度数、しかし、のGeForce 9600M GTを使用することです。ですから、OpenCLのこのような問題に対処する良い方法はありますか?私は浮動小数点数を切り捨ててこの問題を回避するためにいくつかの小数点以下を追加することを考えましたが、それはちょっと混乱したようです。

答えて

7

これはかなり一般的な問題です。 CPUであっても、メモリオーバーヘッド/帯域幅の2倍を避けるために、倍精度の使用を避けたい場合があります。

GPU用に書かれた数多くの分子動力学およびn体コードは「混合精度」算術を使用しています。粒子の位置と速度を単一の精度として保存しますが、通常は位置の差を保存し、加速度を蓄積するために、いくつかのキー操作に倍精度を使用します。 (グーグル"mixed precision" "molecular dynamics"または"n-body"は結果のトンを与える)。

だから、倍精度演算の数を減らすことができますが、ゼロにはありません。ハードウェアのネイティブサポートよりも高精度の算術演算を実装するには、2つのフロートを使用して2倍をエミュレートするソフトウェアエミュレーションを実行します。これを実装した由緒のあるFortranライブラリdsfun90があり、this NVidia forumの誰かがCUDA(NVIDIAのMandelbrotの例の操作に基づいて)で同様のことを実装しました。私は、OpenCLの実装についてはわかりませんが、CUDAからコピーするのはかなり簡単です。明らかにネイティブダブルスほど高速ではありませんが、いくつかの重要な操作のためだけであれば、それほど悪くはありません。

+1

合意された、混合精度のアプローチは間違いなく道のりです – talonmies

+0

丁寧な言い回し! 「混合精度」は、私が探していた技術用語でした。私は、力の集約のために倍精度をエミュレートすることで、最初のスタブを取って混合精度モデルを実装し始めました。それはずっと遅く、私の486sxの時代を思い出させます。私の方法の最適化は多くの助けになります。しかし、おそらく、ネイティブの倍精度サポートでGPUを取得するのは、より良い時間/価値のトレードオフであり、力の集計には複数の精度が使用されると思います。素晴らしい答え!ありがとう! – Pridkett

14

あなたは、数値解析の分野で基本的な質問のほとんどに当てはまりました。これらの問題がどのように扱われているかについての読書を準備する必要があります。

まず、あなたの問題は対称性を持っている場合、あなたは必要な計算量を減らすためにこれを利用することができ、またによる数値誤差に任意の自発的対称性の破壊を取り除きます。

第二には、同じ有限精度を扱う場合でも、いないすべてのアルゴリズムが等しいことを実現:いくつかのアルゴリズムは、他よりもnumerically stable多くです。より高精度の算術演算を使用しても数値的な不安定性が排除されるわけではありません。現在、重力シミュレーションではEuler's Methodに相当するものが実装されている可能性があります。倍精度に切り替えることなく、Runge-Kuttaのような高次の方法を使用すると、シミュレーションをより安定/正確にすることができます。あなたがforce-directed graph layoutをやっているよう

最後に、それが聞こえます。物理的なシミュレーションを単に実行するだけでは、局所的な最適値を見つけ出す傾向があり、開始位置に大きく依存します(通常はかなり不安定です)。リンクされたwikiページには、問題を解決するためにはるかに良い仕事をすることができるいくつかの他の方法が記載されています。

+0

優れた答え。今度はオイラーの方法をわずかに変更したバージョンを使用していたのは間違いありません。 Runge-Kuttaフォースインテグレータを実装することで、モデルが大幅に改善されました。これをCPUモデルにも移植します。しかし、Runge-Kuttaを適用しても数値の不正確さが生じても、倍精度に切り替える場合と同様に時間がかかります。 – Pridkett

関連する問題