RSS Twitter Facebook

2011/10/20 (2011年10月 のアーカイブ)

Javascriptでもデノーマル問題はあるんだよ!

Javascript でもデノーマル問題はあるんだよ!っていう話

PCで音関係の処理をする時の問題のひとつに「デノーマル問題」があります。DAWやプラグインが妙に重くなる時がある、なんていうのが以前はよくありました。Javascriptは今までこんな事に使われていなかったから、問題になる事はなかったんだろうけど、将来は表面化するかも知れません。

ネイティブの世界では、SSE対応のCPUでDAZやFTZと呼ばれるモードが増設され、デノーマルをゼロとして扱う事が可能になって解決する手法が確立されたって所なんですが、この先Javascriptのエンジンでもこのあたりを考慮する必要があるんじゃないかなあ。

て所でデノーマルについてちょっと解説


for(var f = 0.1 ; f != 0 ; f *= 0.1) {
}
さて、0.1 をかけ続けるこのループはいつ抜けるのでしょうか!?
数学的にはいつまでたってもゼロにはならないけど、PCの処理ではアンダーフローしていつかはゼロになります。音の減衰曲線なんかもこんな感じです。

Javascriptの数値は倍精度なので、指数部は11ビットあります。表現可能な一番小さい数は1×2の-1023乗までです。これを10進の桁数であらわすと1桁(10)がlog2(10)=3.32ビット相当なので 1 ×10の-308乗程度になります。

しかし、いきなり0になるのは忍びないので、特殊フォーマットを使った近似表現でもうちょっと頑張ってみるか、っていうのがデノーマル。
やってみましょう。

for (f = 0.1; f != 0; f *= 0.1) {
    Time1 = new Date();
    for (var i = 0; i < 1000000; ++i) {
        result = f * 0.1;
    }
    Time2 = new Date();
    document.write((Time2 - Time1)+"mSec:"+f+"<br/>");
}
document.write("Loop Exit!!");

100万回ずつループして時間を測定しています。
結果は・・・

10の-323乗までゼロにならないですね。
で、問題はその実行時間。10の-308乗にさしかかるとデノーマルモードに突入。いきなりパフォーマンスが1/20くらいに!!!
やっぱりJavascriptでもデノーマル問題は健在なのであった。
リアルタイムで音を合成するようなアプリだとデノーマルが出てこないように対処しないとね。

・ある程度小さくなったら0にするとか計算を打ち切るとか。
・小さくならないように微小信号を常に入れる。

のどっちかだよ

ついでに各ブラウザを比較

やっぱりChromeとFirefoxは良いライバル同士のようだ。一昔前にネイティブで書いてた時くらいのパフォーマンスくらいはありそうだよ。
Operaもそこそこ頑張ってるね。IEをはよなんとか!て感じか。

参考に:「デノーマルの罠」

Posted by g200kg : 2011/10/20 11:22:09