Sony Vector Math library and SIMD math library

by syoyo

Sony Vector Math library and SIMD math library open sourced
http://bulletphysics.com/Bullet/phpBB2/viewtopic.php?p=4884

[En]

TODO

[Ja]

MUDA で数学関数(log とか sin とか)どうするかな、と web をあさって見つけました。
PPU と SPU 向けですが、4 要素同時の logf, sinf とかがあります。
license は BSD と緩いので、これを SSE 版に porting しようかと思います。
というかこれこそコードを MUDA で書くのがいいかも。

経緯

精度はそれほど正確でなくていいので SSE 使って早い数学関数ルーチンはないかなぁと探していたのですが、
見つかるのはベンダが提供している SIMD Math Library(Accelerate.framework on Mac とか)とかばかり。
これらはみんな closed source なのでどの環境でも使えないという問題がある。

コードが公開されているものをと探したのですが、なかなか見つからず、
しょうがねー newlib の libm コードを MUDA(SSE) で書きなおすかなーと思っていたところに
Sony のライブラリを見つけました。

経緯にいたるまでの経緯

MUDA で数学関数どうすっぺかなーと考えていて、とりあえずまずは普通に gcc とかが吐くコードを試してみました。
ひとまず対象は logf() でこんな感じのコードを書いてみて、

http://lucille.svn.sourceforge.net/viewvc/lucille/angelina/muda/bora/log/

測定に AMD simulation utilities を使ってサイクル数を計ってみました。
(一部落ちるケースもあったけど、そのときは AMD のドキュメントでレイテンシを確認とかで推定しました)

普通の logf() (linux libm)

1000 サイクル以上かかりました。げげげー…
こりゃ MUDA では使えないね(デバッグ時とか以外は)。

gcc の -ffast-math で生成される logf()

100 ~ 150 サイクルくらい。げげー。
FYL2X っていう x87 インストラクションを使うようになるのですが、これが AMD では 100 以上サイクルがかかる。
(Intel でもそれくらいかかるみたい)
4 要素同時になって 100 サイクルならなんとか許容できるけど、1 スカラで 100 サイクルはかかりすぎ。

gcc の -mfpmath=sse とか cl.exe がリンクする数学関数

-mfpmath=sse だと普通に libm の logf() を呼ぶようです。
libm とかの実装次第ですが、私の環境では SSE は使われずに普通の logf() の振る舞い(1000~ サイクル)でした。

Visual C++ がリンクする数学関数は、Win 版の AMD Codeanalyst の結果を見ると
SSE2 サポートな CPU では SSE 版ルーチン(double 精度)が呼び出されていました。
これは 100 サイクルくらい。

-mfpmath=sse & -ffast-math

で 4 要素同時な SSE 近似数学関数が呼ばれることを期待したいが、、、
まぁ無いことは分かっています。
このコンパイラオプションの組み合わせだと gcc は FYL2X ではなくて
遅い方(精度がある(?) libm のほう)の logf() を呼ぶコードを吐くようです。

まとめとか

– 基本的には ojbdump でどんなコードになっているのか確認する。
– AMD SImulation utilities(linux), Codeanalyst(win) でインストラクションシミュレーションさせてサイクル数を確認
– mul や add が 1 cycle とかで処理できる世界なのに, 数学関数が 100~ というのは耐えられない。
これでは gpgpu とか *UDA をツブせないではないか。
– newlib とか [1] からの数学関数の近似計算ルーチンを SIMD に移植しようかと考えていたら、
Sony から 4 要素同時の数学関数の PPE, SPE 版が open source で出ていた。なんていいタイミング。
(内容は newlib’s libm の実装とはちょっと違うみたい)
– Sony のを参考にして MUDA なり SSE で書き直してみる
– たとえば logf なら 4 要素で 100 サイクルくらいでできると見込む(1 要素 25 cycle)。これならまあ耐えられる。
それ以上のようなら [2] とあまり差がなさそう。ちなみに glibc の結果は私の環境の logf() のサイクル数と大きな違いがありますね。
libm のバージョンや AMD と Intel の違いとかでしょうか。
– MUDA で書くなら、アノテーション機能を MUDA に追加したりして、精度を指定とかして精度に従ったコードが生成されるようにしてみる.
(さらにいうとたとえば Interval arithmetic なコードを吐くとか)

[1] Faster Math Functions
http://www.research.scea.com/gdc2003/fast-math-functions.html

[2] Accurate Math Functions on the Intel IA-32 Architecture: A Performance-Driven Design
http://rnc7.loria.fr/astafiev.pdf

Advertisements