KDVプログラミング講座 第2回のまとめ

もういい
C言語でググると一番上に出てくる初心者のためのポイント学習C言語でいきます。
一応なにかといろいろできるように1〜5章をやりました。


DirectXのベクトルやら行列やらの入ったD3DXライブラリはCPUを判別してx87だのMMXだのSSEだの3DNowだのの命令を使うらしい。
使える場合は使えるだけ使って速くはなるのだが、それが原因で異なるCPU間で演算結果に微小な違いが出て、リプレイずれなどの問題が起こることがあるらしい・・・。
「気をつけろ」だのなんだの言ってごまかされても結局はD3DXと同じルーチンを全部自分で書くか誤差をなんとかするしかないわけで・・・。
とりあえずレジストリをいじれば拡張命令を使わずすべてx87で行うようになるらしいが、うーん、どうかなあ・・・。
速度なんていらないよ(泣)。PCゲームは動かす環境の性能が1人1人違うわけで、数学計算を高速化してもちょうどそれでギリギリ快適かそうでないかの境目にいたごく一部の人のメリットにしかならないわけで・・・。
というかレジストリ以外での設定方法つけて><


やる気がものすごく下がった


ついでに以前見たことがあった気がするがDirectXは初期化時にFPUの設定を変更して計算精度をfloatサイズ相当にするそうだ。DirectX全体がfloatで最適化されているから。
すると、DirectX以外のコードも(自分のコードもライブラリのコードも)影響を受ける。今のFPU(x87)はfloatとdoubleの違いはメモリへの置き方だけで、演算は80bitで行っているらしい(精度は設定レジスタがある)。よって、double同士の演算結果をdoubleに入れると

(メモリ)64bit -> (FPU)80bit
(メモリ)64bit -> (FPU)80bit
演算結果: 80bit(精度はfloat相当)
(メモリ)64bit <- (FPU)80bit(精度はfloat相当)

という悲しい結果に。doubleにfloat相当の精度の数値を入れることになり、完全にメモリの無駄遣いになります。こちらは一応デバイスの作成時の引数にフラグを入れて回避することができるようだ・・・。
ただし多分DirectXでのすべての浮動小数点数処理の前後に精度設定と元に戻す処理が入ってパフォーマンス低下が起きるということなのだろう。


MS Specific:

  • _controlfp
  • _statusfp
  • _clearfp

というFPUの精度や例外の設定レジスタを操作・取得する関数が用意されています。アセンブラを書かなくていいです。


小数の経験が少なすぎる。もうほんと。
FPU操作のアセンブラガリガリやろうかしら。
64bitではSSEに完全移行で他は完全廃止だそうです。
ちょっと64bitが恋しくなった。


結論:
Q.結局どうすればいいの?
A.無理。Javaを使って浮動小数点数を使うクラス全部にstrictfpをつける。MathではなくStrictMathクラスを使う。パフォーマンスなんて知るか。