4

私はニュートン法のヤコビシータ関数のフラクタルを生成しようとしてきました。mpmathでの試行には長い時間がかかるため、Cでコーディングしてみました。

次の画像を生成するために使用されるソースは次のとおりです。http://owen.maresh.info/allegra.cであり、 gcc allegra.c -o allegra -lmでコンパイルされ、./allegra>jacobi.pnmとして呼び出される必要があります。


(ソース:maresh.info

だから:*評価をスピードアップする方法はありますか?これはこの画像を生成するのに30分以上の壁時間を要しましたか?(映画を作るために、これらの画像を異なる名前ですばやく作成できるようにしたいと思います)*シータ関数の定義に誤りがあることはわかっていますが、原因を特定するのに苦労しています。不連続性。

参考までに、この画像は、ϑ 3(z、0.001-0.3019 * i)で標準のニュートン法を実行して作成されました。

4

2 に答える 2

3

まず、-O3および/またはでコンパイラの最適化を有効にしてみてください-fast。私のシステムでの簡単なテストでは、1倍または3倍のパフォーマンスの向上が見られました

また、パフォーマンスを向上させるためにコードの変更を試す場合は、メインループを次のように変更することで、実行時間を短縮することが有益です。for(a=0;a<10 /* 512*/ ;a++)

注:GCCは複素数をサポートしており、マニュアルページ、、、およびインクルードファイルを参照complexcpowcexpください。/usr/include/complex.h

アプリケーションのプロファイルを作成したところ、ほとんどの時間がで費やされていることがわかりましたpowc()。残念ながらcpow()、数学ライブラリから使用するようにpowc()を変更した場合、実装よりも実行速度が遅くなりました。

実行しているシステムに複数のコアがある場合、外側のメインループをOpenMPと並列化することで、実時間はかなり簡単に短縮できます。ただし、アニメーション用の画像フレームを生成する場合は、各フレームを個別のプロセスで生成するのが最も効率的です(xargs -P # -n 1このタイプの粗い粒子の並列化が好きです)。

于 2012-04-13T08:09:53.193 に答える
3

あなたが IRC でこれについて言及したとき、私は奇妙な気分でそれを最適化するのにしばらく費やしました。私の Mac では、コンパイラの最適化フラグを除いて、少なくとも 4 倍高速になりました。他のプラットフォームではさらに高速です。

私は...高等数学に関しては無知ですが、最適化についてはいくつか知っています。これでの計算は、expc() の実装をシステム cexp() に置き換えたことを除けば、元の計算と同じであり、同一の出力が生成されると思います。それがまだ十分に数値的に安定しているかどうかを判断する必要があります。

Brian Swift が指摘したように、powc() は高価です。これは、log() および pow() 関数が原因です。

大きな勝利だったもの:

  • pjtheta() と pjtheta3() の計算は組み合わせることができます
  • その計算は newt() の内部ループにすることができ、その一部は内部または両方のループの外に移動できます
  • cpow() は Brian (および私) にとっては遅いかもしれませんが、cexp() は、少なくとも私のマシンでは、あなたのコードよりも確実に高速です。両方の方法を試してください
  • コンパイラ フラグの -ffast-math は、動作の悪い数値に対する標準準拠のサポートを削除し、大幅に高速化します

もう 1 つの大きな成果は、cexp() と cpow() の算術演算を単精度に変換したことですが、これはわずかに異なる結果をもたらしました。

プログラムを認識できなくなっているかもしれませんが、次の場所にあります。

https://github.com/cgull/allegra.git

私はさらにいくつかのことに気付き、さらに 25% から 33% をノックアウトしました (まあ、これは収束する反復関数です!)

高等数学をよく理解している人なら、さらに 2 倍から 4 倍のパフォーマンスを発揮できるはずです...

于 2012-07-07T04:39:51.027 に答える