2015年1月19日月曜日

fmath.hppでexpを高速化するときにハマる事。



以下を使うだけなのですが、ちょっと工夫が必要です。


http://www.slideshare.net/herumi/exp-9499790


https://raw.githubusercontent.com/herumi/fmath/master/fmath.hpp


fmath.hppではSSEを使った高速なexpの実装がなされています。


gccやclangはもちろんVCでも2008移行なら通るみたいです。(VC2010で通るのは確認)


erf等の超越関数も多くはexp(区分近似多項式)の形で実装されているので


boostなどヘッダファイルとして与えられている実装なら高速化できます。






#include<fmath.h>
#define exp(...) fmath::expd((__VA_ARGS__))
#define expf(...) fmath::exp((__VA_ARGS__))
#include<boost/math/special_functions/erf.hpp>
#define erf(...) boost::math::erf((__VA_ARGS__))


気を付けなければいけないのはc++の場合関数マクロの引数がXじゃなくて...になる事。


特にboostはコレにしておかないとコケます。


マクロ展開はコンパイラに先立って行うので、「,」を見つけると機械的に複数の引数として検知します。なのでexp( TemplateFunction<a,b>(1)); というようなテンプレート関数を引数に取るときに誤った処理をしてしまうのです。


あと細かい話しだとexpをdouble型としていますが、expはfloat型もあります。なので本当は型によってfmath::expdとfmath::expを呼び分けるようにしてあげる必要がありますが、私自身はfloatをめったに使わないので、上のように手抜きしています。





上の方法で全てのソースコードにexpの入れ替えができるというわけではないですが、あらかたうまくいきます。





0 件のコメント:

コメントを投稿