Linuxを中心とした話題を投稿予定。 使用ディストリビューションであるFedoraが中心になると思われます。http://oedipa.wiki.fc2.com/にてTips Wikiを公開してます。
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
DSPってのは奥が深いな・・・
なんか色々と勘違いしていたことが発覚。畳み込みはあくまで小数同士の積和だから、ゆーても整数部の桁はほとんどいらないんだよな・・・。そんでもって符号付き16bit同士の積だと必要な桁数は31bitだとか。まー符号付きの16bitだと、実際に数値を表現しているのは15bitだから、15bit同士の積を考えればいいはず。必要な桁数は30bit、そんでもって符号ビットの1bitを加えれば31bitになるって計算でいいのかな?けど、DSPでは実際には小数部は30bitしか扱わないんだとか。なんでだ・・・?
最上位ビットを符号部、次のビットを小数第1位として4bit同士の積を考えてみる。
例えば、
0.111 = 0.875
0.010 = 0.25
の積を考えたら、最上位ビットを無視すると
       .111
x      .010
-----------
          0
      1.11
+    00.0
------------
     01.110
これを3bit右シフトした0.001110 = 0.21875ってのが計算結果になる。あとは符号ビットを加えるだけ。小数同士の積では結果は必ず1以下となるから、途中結果はどうあれ最終結果は下位ビット側に乗数の小数部桁数分伸びる(今回は3bit)。小数点の位置が同じ固定小数同士を掛けるなら倍の桁数を用意しておけばその精度同士の積が誤差なしで得られることになる。ただし、途中結果は上位側に結果が伸びるため、そちらがオーバーフローする可能性がある。今回の例でも、右シフトする前の結果は整数部に値が入ってしまっている。これだと右シフトした際に正しい結果が得られない。
ただ、予め小数部に十分な桁数を用意できているとするならば、先にビットシフトをしておいてから演算を実行すれば上位ビットへのオーバーフローは防げる。つまり、
       .000111
x      .010
--------------
             0
      0.00111
+     0.0000
--------------
      0.001110
とすることで同じ結果が得られる。これなら上位にビットが溢れることはない(はず?)。例えば
0111 = 0.875
0111 = 0.875 の積を考えると、
       0111000
x      0111000
--------------
     0111000000
   0111000000
+ 0111
000000
--------------
  110001000000

となり、3bit右シフトすると0.110001000=0.765625となります。予め3bitずつ右シフトしておいたとすると、
      01110000
x     00001110
--------------
       1110000
      1110000
+    111000
0
--------------
   01100010000

となり、0.110001000となるため同じ結果が得られます。どちらの方法をとったにせよ、下位3ビットは確実に0となるため、本来符号bitを除けば7bit確保できるけれど6bitで十分と言うことになります。これを単純に32bitに置き換えて考えると、なるほど確かに小数部は30bitで事足りるという結論が導けてしまう・・・。ほんっと、昔の人は賢いよな・・・。
ところで、実はこれでもまだ具合が悪い。整数と見立てて考えると分かりますが、符号bitを含めて4bit同士の積を考えていますから、その結果は明らかにオーバーフローしています。これは具合が悪い。ならば今度は両方を3bit右シフトしておき、結果を3bit左シフトすることを考えます。
       00001110
x      00001110
---------------
       00001110
       0001110
+      001110

---------------
       01100010

これでオーバーフローの心配がなくなるはずです。というより、溢れた桁の分は捨て置くのでこれで4bit同士の固定小数の演算結果が得られていることになります。取り出すときにはこれの上位4bitを取得すればよいことになります。つまりは0.75となるわけですね。まぁ取り出すときだけ丸め処理を入れればいいと言うことだけ押さえておけば十分でしょう。
が、これは積の場合で、除算はまた違った結果を生むんですよね・・・。被除数の絶対値が除数の絶対値よりも大きければ絶対値が1以下に収まりますから問題になりませんが、そうでない場合、絶対値が1を超えるのでオーバーフローを起こす羽目に。
ん~、今度実装するアルゴリズムは学習同定法がベースだし、どう考えたって絶対値は1超えてくるんだよな・・・。DSPで学習同定法を実装するときってどうやってんだろ・・・? まっさか浮動小数ではないだろうしなぁ・・・。FFTは絶対値を1以下に抑える方法がちゃんとあるからいいけれど、逆フィルタの生成とかだと除算が入ってくるだろうし・・・。調べてみるか。
ふぅむ、実用レベルまで持って行くのはかなりしんどそうだな・・・^^;
関連記事
スポンサーサイト
コメント
この記事へのコメント
コメントを投稿
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可
 
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。