x86 系 CPU の float/double

float は遅い?

http://d.hatena.ne.jp/NyaRuRu/20060615

http://www.shudo.net/publications/swopp0107/shudo-swopp200107-strictfp.pdf

x87 が 80-bit の精度を持っており、精度を指定して計算する命令を持っていないことが原因。

float の精度をそろえるために演算するたびにメモリに書き出して読み直すとか悲惨すぎる。
Java では関数に fpstrict をつけることでこれが行われる。

http://homepage1.nifty.com/herumi/prog/prog90.html

x86 においては、float と double はメモリに置くサイズという違いでしかなく、演算精度とは関係ない。
演算精度は FPU コントロールレジスタで指定する。

とはいえ、DirectX アプリケーションを作っている分にはそれほど意識しなくても問題はなさそうだ。
DirectX が(勝手に)FPU コントロールレジスタを変更してるから。

DirectX Graphicsは描画デバイス作成時に、x87 FPUのコントロールレジスタが持つ丸め精度ビットを、デフォルトである倍精度相当の53bit精度から、単精度に相当する24bit精度に変更します。
これにより以後のx87 FPUによる浮動小数点演算は、仮数部の丸め精度を24bitとして扱うようになります。この設定は特にDirectXランタイムの内部に限らないため、同じスレッドで実行される物理演算や音声計算の結果が影響を受けることになります。
バイス作成時にD3DCREATE_FPU_PRESERVEを指定すると、DirectX Graphicsは(少なくとも見かけ上は)丸め精度に変更が行われなかったかのように振舞います。

ただ、例えばゲームは DirectX で動かすけどツールは OpenGL だとか、マルチプラットフォームのゲームとか、ツールで x86 以外のマシンも使うとか、そういう時は気をつけないといけない。

http://d.hatena.ne.jp/NyaRuRu/20050424

いわゆる x64 Edition な Windows では,浮動小数点演算が SSE/SSE2 に完全移行することになる.
コンパイラx87 FPU, MMX, 3DNow! 命令を含むコードを出力しない.ただしこれは 64-bit アプリケーションに要求される仕様で,WOW 上で実行される 32-bit アプリケーションについては従来通り x87 FPU が使用可能.
ただしコンテキストスイッチ等の関係でFPU コントロールレジスタの変更追跡が行われるようになった模様.

x87 FPU と決別したことで従来可能だった 80-bit 精度計算に比べて計算精度が悪化する場合もある.しかし業界標準的には SSE/SSE2 が FP-strict 準拠のためありがたい面もある.もちろん従来の x87 環境と計算結果が変わってしまう可能性があるので,ゲーム関係ではリプレイ再現性問題などに注意.

64-bit プログラムになると結果が変わってしまいそう。
でも、FP-strict 準拠になるから、プラットフォームの違いを意識しないでよくなり、double よりも float が遅いという問題も無くなる。

今のところは、x86 + x87 の計算結果が変態なので、きちんと考えておかないとだね。