6

他の質問に関連して、SOR(Successive Over-Relaxation)法を使用するようにスパース行列ソルバーを変更しました。コードは次のようになります。

void SORSolver::step() {
    float const omega = 1.0f;
    float const
        *b = &d_b(1, 1),
        *w = &d_w(1, 1), *e = &d_e(1, 1), *s = &d_s(1, 1), *n = &d_n(1, 1),
        *xw = &d_x(0, 1), *xe = &d_x(2, 1), *xs = &d_x(1, 0), *xn = &d_x(1, 2);
    float *xc = &d_x(1, 1);
    for (size_t y = 1; y < d_ny - 1; ++y) {
        for (size_t x = 1; x < d_nx - 1; ++x) {
            float diff = *b
                - *xc
                - *e * *xe
                - *s * *xs - *n * *xn
                - *w * *xw;
            *xc += omega * diff;
            ++b;
            ++w; ++e; ++s; ++n;
            ++xw; ++xe; ++xs; ++xn;
            ++xc;
        }
        b += 2;
        w += 2; e += 2; s += 2; n += 2;
        xw += 2; xe += 2; xs += 2; xn += 2;
        xc += 2;
    }
}

奇妙なことにomega、(緩和係数を)増やすと、実行速度はさまざまな配列内の値に劇的に依存し始めます。

の場合omega = 1.0f、実行時間はほぼ一定です。初めてomega = 1.8、これを10回実行するのに通常5ミリ秒かかりますがstep()、シミュレーション中に徐々に100ミリ秒近くまで増加します。を設定omega = 1.0001fすると、それに応じて実行時間がわずかに増加します。値が高いomegaほど、シミュレーション中の実行時間が速くなります。

これらはすべて流体ソルバー内に埋め込まれているため、スタンドアロンの例を思い付くのは困難です。しかし、私は初期状態を保存し、タイムステップごとにその状態でソルバーを再実行し、実際のタイムステップを解きました。初期状態では高速でしたが、後続のタイムステップでは徐々に遅くなりました。他のすべてが等しいので、それはこのコードの実行速度がそれらの6つの配列の値に依存していることを証明します。

これは、g ++を使用するUbuntuで再現可能であり、VS2008で32ビット用にコンパイルする場合は64ビットのWindows7でも再現可能です。

NaNとInfの値は浮動小数点の計算では遅くなる可能性があると聞きましたが、NaNまたはInfsは存在しません。フロート計算の速度が入力数値の値に依存する可能性はありますか?

4

2 に答える 2

5

最後の質問に対する簡単な答えは「はい」です。非正規化された(ゼロに非常に近い)数値は特別な処理が必要であり、はるかに遅くなる可能性があります。私の推測では、時間が経つにつれて、彼らはシミュレーションに忍び寄っています。この関連するSOの投稿を参照してください:浮動小数点演算の実行時間

非正規化数をゼロにフラッシュするように浮動小数点コントロールを設定すると、シミュレーション品質の影響はごくわずかです。

于 2010-03-06T15:46:58.860 に答える
0

セリオンの答えは正しいものであることがわかりました。彼がリンクしている投稿は、非正規化された値のゼロへのフラッシュをオンにするように言っています:

#include <float.h>
_controlfp(_MCW_DN, _DN_FLUSH);

ただし、これはWindowsのみです。Linuxでgccを使用して、インラインアセンブリのようなもので同じことをしました。

int mxcsr;
__asm__("stmxcsr %0" : "=m"(mxcsr) : :);
mxcsr |= (1 << 15); // set bit 15: flush-to-zero mode
__asm__("ldmxcsr %0" : : "m"(mxcsr) :);

これは私の初めてのx86アセンブリなので、おそらく改善できるでしょう。しかし、それは私にとってはトリックです。

于 2010-03-07T11:33:04.897 に答える