MinGWとSSEとアライメント

実行されるプログラムを首尾一貫して自身で用意する場合は最低限のお約束だけであまり気にしないでもよさげ。

A)最低条件:、

1)変数は int f __attribute__((aligned(16)));のように確保。

2)メモリブロックの確保は _aligned_malloc(n,16)/_aligned_free()関数を使う。
 MinGWではmsvcrt.dllの7.0xから使える物として定義されているので、__MSVCRT_VERSION__=0x0700をdefineして有効にする。
 WinXP SP3の現時点で7.0xになってるけど、Win2Kだと6.1x止まりだったような気がするから注意。
 状況が許すならmsvcr70.dll(7.0.9x)~msvcr90.dllを使うのもあり?


 第三者のプロセスにぶら下がる物(DLL等)の場合はスタックをそれから引き継ぐので(A-1)では結果を保障出来ない。
 渡ってくるアドレスが0x~1Eとかだった場合、1Eを0として+F(16)されるだけで2Eにしかならない(16alignでない)みたいな。(LWで0x~54とか渡されました、ええ。)

B)対策:

1)スタックに拠らない(?)static変数にしてしまう。 static int Var __attribute__((aligned(16)));等。

2)各関数に __attribute__((force_align_arg_pointer))を付ける。 __attribute__((force_align_arg_pointer)) void Func();等。
 関数内で__attrib~align()を使ったauto変数は適切なアライメントを得られる。
 但し、MinGWのVer4.2.0辺りからの物なので、それ以前では使えない。
 関数突入毎に補正されるから微妙にロスがあるかも。

3)コンパイルオプション -mpreferred-stack-boundary=Nで結果的な補正を得る。 defaultはN=4(2の4乗)。
 但し、ちょっとしたテストで結果的に使えそう、というだけで適正な方法かは不明。
 親プロセスがどれだけずれているかを確認出来る必要があり、試験的にNを決める必要がある(一度落とせばDrWatson32でも見れるけどw)。
 モジュール内の関数/変数全てに(B-2)のような補正が掛かる事になり、アライメントが不要な関数/変数にも影響が出る。 悪影響になる可能性もある。(LWで0x~54の時、N=2にしたら動いた、ってだけだしw)


その他の力技補正?(参考: http://kikyou.info/diary/?200610、 http://d.hatena.ne.jp/yupo5656/20040627)
まだ試してないけど。

ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 0

この記事へのコメント

この記事へのトラックバック