2009年09月10日

対数、対数、対数

個人用メモ

log(x) (底はネピア数)をFPUなしで(超)速く求める
光成滋生氏のCコードをイントリシック命令を使ってSSEに変換した
計算1回で4個分のlog(x)が計算できる
ttp://homepage1.nifty.com/herumi/adv/adv43.html#014
No.14が2つあるせいで表示がずれてる。本当はもう1段上からが高速logルーチンの解説
この人頭良すぐる。Talor展開や積分はそれなりに分かるが(嫌というほど授業でやらされたし。ちなみに合格点ぎりぎりでした。てへっ)、ローラン展開って何ぞ。チェビシェフ多項式って何ぞ。
てかどっちも東大の入試では普通に出題されてやがる。こんなもん誰が考え付いたんだよ。んもぅ
この方京大の出だから計算できて当然かもしれんが、某ベンチャー企業が暗号解読したニュースがあって(たしかNHKの深夜番組に出てた)、その時の共同研究者がこの人だった。スゴス
午後のこーだ(MP3<->WAV変換ソフト)作ったのもこの人。起動すると萌え画像が出るアレ。特許関連でいろいろとあったらしいが、今でも重宝している。LameやiTunesはめんどくさい
コンパイラのバグにひっかかった。うんこンパイラ。

__m128 herumi_logC_intrin(__m128 x)
__m128i p = *(__m128i*)&x; // p = (unsigned int *)&x;
__m128i b = _mm_sub_epi32(_mm_srli_epi32(p, 23), _mm_set1_epi32(127)); // b = (*p >> 23) - 127;
__m128i pp = _mm_and_si128(p, _mm_set1_epi32(0x007FFFFF));
p = _mm_or_si128(pp, _mm_set1_epi32(0x3F800000));
__m128 a = *(__m128*)&p;
const __m128 XMMSQRT2 = _mm_set1_ps(1.41421356f);
//__m128 z = _mm_mul_ps(_mm_sub_ps(a, XMMSQRT2), _mm_rcp_ps(_mm_add_ps(a, XMMSQRT2))); // 精度が低くていい(10進で6桁くらい)ときはこっち
__m128 z = _mm_div_ps(_mm_sub_ps(a, XMMSQRT2), _mm_add_ps(a, XMMSQRT2));
__m128 zz = _mm_mul_ps(z, z);
__m128 zpbc = _mm_mul_ps(zz, _mm_add_ps(
_mm_set1_ps(0.6664778517f), _mm_mul_ps(zz, _mm_set1_ps(0.4139745860f))
));
__m128 zpb = _mm_mul_ps(z, _mm_add_ps(zpbc, _mm_set1_ps(2.0000006209f)));
z = _mm_add_ps(zpb, _mm_mul_ps(
_mm_set1_ps(0.693147181f), _mm_add_ps(_mm_set1_ps(0.5f), _mm_cvtepi32_ps(b))
));
return z;

…き、きたねー。2度と見たくないタイプのソース
ちなみに、対数の公式を使えば、基数がeでなくても使えます。log2(x)なら、return z;の前に
z = _mm_mul_ps(_mm_rep_ps(あらかじめ計算しておいたLOG_E_2), z);
すればいいはず

で、↑の逆アセ結果を使ってSSEの勉強して分かったこと

・32bit即値を18bitXMMレジスタへ4個コピーして転送
つまり、_mm_set1_epi32(__m128i)の中身
mov eax, (即値)
movd xmm0, eax
pshufd xmm0, xmm0, 0
pshufdでsrcとdestに同じレジスタを指定するのがミソ
今使っているCore 2 Duo(初期)のCPUなら、movで1clock、movdで2clock、pshufdで3clock (clockとHzは意味的には同じだそうだ)
合計6clock。遅すぎ。movdqaやmovapsなら2clockで済むのに(ただしL1キャッシュにヒットするとき)。
ちなみにSuper Shuffle Engineを持つ後期のCore 2 Duo(Penryn)は、pshufdが1clockなので、合計4clock
movdqaだとキャッシュ汚染があるし、これなら許容範囲か
ちなみに、_mm_set1_ps(__m128)はmovapsになる。なんでやねん
posted by 毒渡 at 18:22| Comment(0) | TrackBack(0) | プログラミング | このブログの読者になる | 更新情報をチェックする

2008年02月20日

Windows + VS2005/VS2008でPerlのXSモジュールを作る

やっとperlxstutの一段階目のコードのコンパイルが通った。また2chに助けられた。急いでメモ。

http://pc11.2ch.net/test/read.cgi/tech/1037383722/579-580
質問者はVS2008だが、手元のVS2005 SP1で確認。

>若干スレ違い気味だけど、自分の場合(XpSP2+VC2005)での対処法。

>perl Makefile.pl
>で出来上がった Makefile のなかの、実際にコンパイルが走ってる行で、
>”-MD” となっているところを全て ”-MT” に変更する。
デバッグ切って、マルチスレッド用のライブラリを指定する、と。

>でさらに、リンクライブラリが列挙してあるとこの
>”mscvrt.lib” を ”libcmt.lib” に変更してから、nmake && nmake test を掛ける。
これこれ。これが引っ掛かった。
msvcrt80.dllをSystem32においても、R6034で落ちやがんの。

>これは、詳しくはMSDNのリファレンスを見てもらいたいんだけど、
>.Net がWindowsに入って以降、標準のCランタイムライブラリが、
”libcmt.lib”から”msvcrt.dll”に変更された。(VCでのデフォルトになった。)
>この”msvcrt.dll”は、実体は”msvcr80.dll”(XP+Net2.0+VC2005の場合)へのダイナミックリンクのローダーなんだけど、
>Windows上で有効なCランタイムライブラリが、以前(VC2003以前)は、”libcmt.lib”からのstatic_linkだったのが、
>2005から、”msvcrt.dll”へのdynamic_linkへ変更された模様。
>(だから、以前VC2003で書いてたCソースをそのままVC2005でコンパイルしなおしても、動かないことが頻発)
ほー。なるほど。これは知らなかった。
CRTのバグをWindows Updateで修正できるよう、静的リンクはなしにするという話を聞いたことがあるが、こんな面倒なことになるとは。
古いMakefileを使うなら、VS2003もVistaにインスコしないといけないのか。ってVista対応してないじゃん。うんこチンチン。

あ、壊れた日立のXP機は、店員さんがメモリを付け直したら、正常に動いてしまいました。あーはずかし。ダブルうんこチンチン。
posted by 毒渡 at 19:55| Comment(0) | TrackBack(0) | プログラミング | このブログの読者になる | 更新情報をチェックする

2007年08月27日

Visual Studioでlibjpegのコンパイル

また個人的メモ。

JPEGをnativeな(=.NET製じゃない)プログラムから読むぜっ!
てことで、libjpegをWindows Vista Home Premium + Visual Studio 2005 Pro(VS)でビルド。
UNIXならconfigureしてmakeで終わりなのにマンドクセ。

まずijg.orgからjpegsrcなんとか.tar.bz2を落とす。
jconfig.vcをjconfig.hに名前を変える。ここにmakeするときのオプション一覧が書いてある。
次にmakefile.vcをmakefileに名前を変える。nmakeの/fオプションでmakefile.vcを指定してもできる。
ここでmakefileの読み取り専用を解除しておく。ファイルを右クリック、プロパティね。いじらない人はしなくてもいい。

コマンドプロンプトを起動。
VSの入ってるフォルダの、VCフォルダの下のvcvarsall.batで、パスを通す。
libjpegのフォルダに移動して、nmake。
これでlibjpeg.libのできあがり。
ただ、これはデバッグでコンパイルされるので、CRTの問題や速度の問題で、リリースする時は、nmake nodebug=1としてやる。
ついでにmakefileのCFLAGSに/Oxを足してやるといいかも。

さらにDLL化できないかと思ってググると、なんとできないことが判明
http://www.amy.hi-ho.ne.jp/jbaba/jpeg13.htm
うわー
自分でwrapしろ、と。うんこ。

やっぱり既存のlibjpeg.dll使おうかな…
posted by 毒渡 at 17:17| Comment(0) | TrackBack(0) | プログラミング | このブログの読者になる | 更新情報をチェックする

2007年08月22日

C++のDebugでRun-Time Check Failure

プログラミングメモ。
VS 2005 ProでC++(native)。

Run-Time Check Failure #2 - stack around the variable '変数名' was corrupted.
ってメッセージボックスが出て、なんじゃこりゃと思ってググったら、どうやら配列の範囲を超えてアクセスした場合に出るようだ。

int hoge[] = {3, 4, 5};
hoge[3] = 6; // オワタ\(^o^)/

すげー。便利。
でも「スタックの破壊」じゃ意味不明だよ。
posted by 毒渡 at 20:08| Comment(1) | TrackBack(0) | プログラミング | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。