« むしばになった | メイン | OpenAL »

2006年02月24日

denormalize問題

Intel系のIA-32のCPU(Pentium4とか)で起こる問題で、
ソフトシンセとか書いてると遭遇する。
ディレイとかのフィードバック系のフィルターをつかってると突然CPUの処理が重くなる。

こいつはdenormalize問題というらしく、浮動少数(float, doubleとか)をつかってると起こる
CPUが浮動少数をあらわすのにnormalizeとdenormalizeという2つの方法を使っている。
normalize は exp と 1.XXX..ってなかんじで指数表示
denormalizeは 0.XXXXX(2) ってなかんじで2進数表示
となっているらしい。
浮動少数が0に近くなるとnormalizeではうまくいかなくなるのでdenormalizeの方に切り替える。
この処理が頻繁にはいると、CPUをくわれて突然倍くらいの負荷がかかる。
(ディレイの処理とかでフィードバックの倍率を0.3とかにしたら、どんどん0に近くなるからね)
KSynthが長い間P4で遅かった問題は、この問題のためだった。

調べたところ、この問題の解決法は

#define DENORMALIZE(fv) (((*(unsigned int*)&(fv))&0x7f800000)<0x08000000)?0.0f:(fv)

ってマクロをかいて

flt = DENORMALIZE(flt);

ってなかんじでコードを、フィードバックされてるところに追加してやれば解決する。
とりあえず、KSynthに関しては70 - 80%くっていた使用率が、30%程度になった。


とまぁpouet.netの掲示板で教えてもらいましたが、
検索したら結構引っかかったし、ソフトシンセの分野では結構ポピュラーな問題のようだ。
さらに詳しく知りたい人はIA-32 Intel Architecture Software Developer’s Manual
の88ページあたりを参照するとよい。

投稿者 kioku : 2006年02月24日 01:58