为什么这个SOR求解器的速度取决于输入?

Tho*_*mas 6 c++ floating-point optimization sparse-matrix

与我的其他问题相关,我现在修改了稀疏矩阵求解器以使用SOR(连续过度松弛)方法.代码现在如下:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在奇怪的是:如果我增加omega(松弛因子),执行速度开始显着依赖于各种数组内的值!

因为omega = 1.0f,执行时间或多或少是恒定的.因为omega = 1.8,第一次,执行这step()10次通常需要5毫秒,但是在模拟期间这将逐渐增加到接近100毫秒.如果我设置omega = 1.0001f,我看到执行时间相应略有增加; 越高omega,模拟过程中执行时间越快.

由于所有这些都嵌入在流体求解器中,因此很难找到一个独立的例子.但是我保存了初始状态,并在每个步骤重新运行该状态的求解器,以及求解实际时间步长.对于初始状态,它很快,随后的时间步长逐渐变慢.由于其他条件相同,这证明了此代码的执行速度取决于这六个数组中的值.

这在使用g ++的Ubuntu以及使用VS2008编译32位时在64位Windows 7上是可重现的.

我听说浮点计算的NaN和Inf值可能较慢,但不存在NaN或Infs.浮动计算的速度是否有可能取决于输入数字的值?

cel*_*ion 5

对你的上一个问题的简短回答是"是" - 非规范化(非常接近于零)数字需要特殊处理并且可能慢得多.我的猜测是,随着时间的推移,他们正在进入模拟.请参阅此相关的SO帖子:浮点数学执行时间

设置浮点控制以将非正规数刷新为零应该处理模拟质量上可忽略不计的事物.