【Q】 GMSソルバーを用いて差分計算を行う際に、単位stepあたりの計算時間が一度遅くなって、また速くなるという現象が見受けられました。これはどういった理由によるものでしょうか?

【A】 おそらく、underflowによる例外処理が発生しているせいではないかと思われます。 通常、震源時間関数は緩やかに立ち上がるため、震源付近に非常に振幅の小さな波動場が生じます。差分計算を行なうと波動の伝播に伴う幾何減衰によりさらに振幅が小さくなり、いずれunderflowを起こしてしまいます。このように、underflowを起こしながらどんどんとwavefrontが計算領域いっぱいに広がってゆきます。震源時間関数が立ち上がる前は、全領域で振幅がゼロであるためunderflowを起こしませし、一度波動場が全計算領域に広がれば当然underflowを起こしません。質問にある、一度計算時間が遅くなり、再び速くなるという現象は、震源時間関数が立ち上がり初めてから波動場が広がりきるまでの間にunderflowにより計算が遅くなっているためであると考えられます。 いずれにしろ、計算領域をP波速度でwavefrontが通りすぎればunderflowは収まりますので、全計算時間にしめるunderflowが起きている時間は、それほど多くはないため、(気持ちは悪いですが)大きな問題となることは少ないと思います。 私が知る限り、回避方法は2つ考えられます。

  1. コンパイラーのオプションで、underflowが起きても無視をさせる仕組みが用意されている場合があります。例えば、SunのBlade 1000で走るSolaris上のFortran90/95コンパイラーの場合、"-fns"というオプションをつけてコンパイルすることにより問題を(ほぼ)回避できます。参考までに、f90のmanページの当該部分を抜粋します。

    > -fns[={no|yes}] > Select SPARC nonstandard floating point
    > 【中略】
    > On some SPARC systems, the nonstandard floating point mode disables "gradual underflow", causing tiny results
    > to be flushed to zero rather than producing subnormal numbers. It also causes subnormal operands to be
    > silently replaced by zero. On those SPARC systems that do not support gradual underflow and subnormal numbers
    > in hardware, use of this option can significantly improve the performance of some programs.
    > 【後略】

    この方法は、適当なオプションが提供されていれば非常に有効です。また、Alphaマシンの様に、defaultで例外処理が発生しないようになっている場合には、このような問題自体発生しません。

  2. あらかじめ、初期波動場として計算領域の全体または一部に小さな擾乱(=ノイズ)を与えておくことによりunderflowが起こる状況そのものを回避することが考えられます。ただし、どのような擾乱を与えればよいのかについて、合理的なアイデアがないので、GMSではこのような回避法を提供していません。

(2003-05-12 更新)