ホーム 道しるべ 憩いの広場 濃緑空間 濃緑研の日記

3DNow!で遊ぼう
ホーム ] ベンチマークサーキット ] [ 3DNow!で遊ぼう ] トピック ] 重力シミュレーション ] うるりさんの物置 ] リンク ] 更新履歴 ]

 

逆数(除算)
逆数平方根と平方根
処理時間を測ろう
配列の扱い・最適化1
最適化2

3DNow!を遊んじゃおうってことで、こんなページを作ってみました。

用意するもの

bulletVisualC++(開発ツール:VisualStudio97とか、VisualStudio6.0の中にも含まれています)
bulletAMD提供の3DNow!SDK(インクルードファイルamd3d.hだけでいいです)
bullet種になるプロジェクトファイルはここからダウンロード(amd3d.hも含まれています)
今回のはVisualC++5.0以上用です。VisualC++2.0や4.0の人はとりあえず自力でプロジェクトファイル作ってください。
test3d.lzh(4K)
test3d.zip(4K)

とりあえず、こんな感じではじめようと思います。

b = a*a;

をやってみます。

#include "amd3d.h"
#include <windows.h>
#include <math.h>
#include <stdio.h>
main()
{
    float    a,b;
    char    buf[80];

    a=1.7320508;

    _asm{
        femms
        movd    mm0,a         //mm0:    ??:     a
        pfmul    (m0,m0)       //mm0    ??:    a*a
        movd    b,mm0         //    b = a*a
        femms
    }
    sprintf(buf,"%f",b);
    MessageBox(GetDesktopWindow(), buf,"Test 3DNow!",MB_OK);
}

とりあえず、種プロジェクトファイルをビルドしてGo!Go!Run!Run!って感じで。

どう?メッセージボックスに 3.0000ってでた?簡単でしょ?

でも、これではSIMD(1命令複数データ)でなくてSISD(1命令単一データ)ですね。

じゃあぁ、つぎは本格的にSIMDしてみましょう。

typedef struct vector {
    float    x,y;
} vector;

main()
{
    vector    v,w;

    char    buf[80];

    v.x = 1.41421356;
    v.y = 2.2360679;

//    w.x = v.x*v.x;
//    w.y = v.y*v.y;
    _asm {
        femms
        movq    mm0,v         //mm0:    v.x     :    v.y
        pfmul    (m0,m0)       //mm0    v.x*v.x:    v.y*v.y
        movq    w,mm0         //    w = v
        femms
    }
    sprintf(buf,"%f %f",w.x,w.y);
    MessageBox(GetDesktopWindow(), buf,"Test 3DNow!",MB_OK);
}

どおです。2.00000と5.00000って表示されました?

movd    mm0,a

は単精度32ビットデータをレジスタ(64ビット)の右半分にロードします。

movq    mm0,v

は32ビットデータ*2(2つの単精度浮動小数点データ)をレジスタにロードします。

pfmulをpfaddとすれば加算、pfsubとすれば減算です。