« 「中卒が金の卵」と呼ばれていた時代... | トップページ | A型インフルエンザ襲来 »

2009年1月 9日 (金)

VC++2005でSIMD命令つかってみました。

P1050577_640 VC++では、MMXやSSE,SSE2でサポートされた命令が使えるということを知りました。そこで、どんな感じで使えるのか実験しました。MMXやSSEでは膨大な量の命令が追加されているのですが、とりあえず16ビットの掛け算にテーマを絞ってみました。
まずはMMX命令です。16ビットの掛け算を同時に4つできます。アセンブラ命令では16bitx16bitの答えは32bitになりますがSIMD命令では答えの下位16bitを返すものと上位16bitを返すものが用意されているようです。このプログラムは下位16ビットを返します。結果はデバッカで確認しました。
void CmmDlg::OnBnClickedBtnMul()
{
__m64 m1;
__m64 m2;

m1 = _mm_set_pi16(1, 2, 3, 4);
m2 = _mm_set_pi16(1, 2, 3, 4);
__m64 m3 = _mm_mullo_pi16(m1, m2);
_mm_empty();
}

最後に_mm_empty()を呼び出すのが必要なようです。これが無いとコンパイルでwarningになります。
warning C4799: 関数 'CmmDlg::OnBnClickedBtnMul' に EMMS 命令がありません。
これは浮動小数点演算プロセッサとMMXレジスタが同じデータを使用するために起こるもので、「もうMMXは終わりました」という命令のようです。これは単に宣言のものではなくて「コストがかかる」という記述がありますので、なんらかの後始末をやっているのでしょう。
ところで、浮動小数点演算については従来の浮動小数点プロセッサより、SIMD系の命令の方が速いようです。浮動小数点演算にSIMD系命令を使用するコンパイルオプションがあるというのをインターネットで見たことがあるので、試してみました。コンパイルオプションで浮動小数点モデルをFast(/fp:fast)に設定すると、このwarningが消えました。
次に、SSE2で拡張された命令を試してみました。

void CmmDlg::OnBnClickedBtnSse()
{// SSE2
_declspec(align(16)) WORD awData1[8] = { 1, 2, 3, 4, 5, 6, 7, 8};
_declspec(align(16)) WORD awData2[8] = { 1, 2, 3, 4, 5, 6, 7, 8};

__m128i mAuto1 = _mm_load_si128((__m128i*)awData1);
__m128i mAuto2 = _mm_load_si128((__m128i*)awData2);
__m128i mAuto3 = _mm_mullo_epi16(mAuto1, mAuto2);
}
こちらの方は_mm_emptyが無くても良いようです。このプログラムではメモリ上からデータを読み込んで掛け算を行っています。16ビットの掛け算を同時に8つ出来ます。
SSEでは読み取り対象のアドレスを16バイト境界にアライメントしなければならないので
_declspec(align(16))という宣言を使用しています。これが無いと実行時に_mm_load_si128でエラーになりました。データによってはアライメントしていなくてもOKという関数も用意されているようですが、そういう関数は遅いらしいのでがんばってアライメントしました。

インターネットで調べたところSSEは5まであるようです。
ちなみにインクルードファイルについてはVC2005ではSSE3まで読み込めます。
#include <mmintrin.h> // MMX
#include <emmintrin.h> // SSE2
#include <intrin.h> // SSE3
//#include <smmintrin.h> // SSE4.1
//#include <nmmintrin.h> // SSE4.2
VC2008は4.2まで読み込めるようです。VC++ではSSE2までの関数ドキュメントがなかったのですが、これらの関数は使われる見込みがないためか、英語ドキュメントしか無いようです。関数名もわかりにくいので「こういう関数が欲しい」という場合に非常に苦労します。
「入門編」の日本語ドキュメントが欲しいところです。
参考URL「IA-32 SIMDの扉」
http://www.icnet.ne.jp/~nsystem/simd_tobira/index.html

|

« 「中卒が金の卵」と呼ばれていた時代... | トップページ | A型インフルエンザ襲来 »

コメント

>浮動小数点演算にSIMD系命令を使用するコンパイルオプション
それ別物
http://msdn.microsoft.com/ja-jp/library/7t5yh4fd(VS.80).aspx

投稿: 名無し | 2009年3月 9日 (月) 10時20分

ご指摘ありがとうございます。すみません。この文章、正しくありませんでした。
/fp:fastを使用するとwarningが消えると書きましたが、再度確認すると、warningは消えませんでした。
ご指摘のコンパイルオプション/archはSSE2を使用する/しないなどの指定を行うもので、これも文脈の主旨から外れるように思えます。/archのオプションを変更しましたが、 C4799は消えませんでした。ご指摘のリンクからのさらにその先までは確認していないので、ご指摘の内容を理解できていないのかもしれません。よろしく御指導おねがいします。

投稿: madono | 2009年3月15日 (日) 20時01分

コメントを書く



(ウェブ上には掲載しません)




« 「中卒が金の卵」と呼ばれていた時代... | トップページ | A型インフルエンザ襲来 »