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

配列演算総括
ホーム ] 上へ ] 普通に時間測定 ] ループ展開・時間測定 ] ペアリング最適化I ] ペアリング最適化II ] x86FPUとの比較 ] 3DNow!SISDと比較 ] [ 配列演算総括 ]

 

 総括というと大げさですが、3次元座標変換のための行列演算のために書いたコードの処理速度を比較表にしてみました。

 またループ演算の影響を差し引くために、100,000,000回の空ループに要する時間を求めてみました。結果はK6-III/450で3.384秒(1ループで15クロック)、PentiumII/350では6.189秒(1ループで22クロック)でした。

PentiumIIはVC++6.0でコンパイルしたコードで計測しました。
1行列演算クロックは実処理時間から空ループの処理時間を引き補正しました。
コード種類 K6-III/450 PentiumII/350 1行列演算クロック
含loop 外loop 含loop 外loop K6-III PenII
C言語(ループ展開)VC++5.0Pro 32.972 29.588 31.826 25.637 133 90
普通に時間計測(3DNow!) 17.985 14.601     66  
ループ展開(3DNow!) 10.415 7.031     32  
ペアリング最適化I(3DNow!) 9.867 6.483     30  
ペアリング最適化II(3DNow!)あれ? 11.012 7.628     35  
x86FPU 29.833 26.449 20.900 14.711 120 52
3DNow!SISD 14.130 10.746     49  

 空ループの時間計測コードを以下に示します。

mtrx(float a[4], float b[4][4], float c[4])
{
}

main()
{
    float    a[4]={0,1,1,0};
    float     b[4][4]={{1,0,0,0},{0,0,1,0},{0,-1,0,0},{0,0,0,1}};
    float    c[4];
    char    buf[80];

long    n;
    DWORD    dt1,dt2;
    double    ddt;
   
    dt1 = GetTickCount();

    _asm{
        femms
    }
    for(n=0;n<100000000;n++)
    {
        mtrx(a,b,c);
    }
    _asm{
        femms
    }

    dt2 = GetTickCount();
    ddt = (double)(dt2-dt1)/1000.0;
    sprintf(buf,"%f %f %f %f\n3DNow!による処理時間は %.3f 秒です",c[0],c[1],c[2],c[3],ddt);
    MessageBox(GetDesktopWindow(), buf,"Test 3DNow!",MB_OK);
}