0

vs2012 を使用しており、SSE と AVX の効率をテストしたいと考えています。SSE と AVX のコードはほとんど同じですが、SSE は _m128 を使用し、AVX は _m256 を使用します。AVX コードは SSE コードよりも 2 倍高速であると予想していましたが、テスト結果は、それらの速度がほぼ同じであることを示しています。

/arch:AVX または /arch:SSE または /NOT SET を選択して、SSE コードにコメントを付けるか、AVX コードにコメントを付けようとします。何をテストしても、SSE コードにかかった時間は約 2138 ミリ秒で、AVX コードは約 2106 ミリ秒です。外側の for ループは、サイクル タイムを増やすために使用されます。

#include "testfun.h"
#include <iostream>
#include <time.h> 
#include <malloc.h>
#include "immintrin.h"
using namespace std;
#define dataLen  800000

void testfun()
{
float *buf1 = reinterpret_cast<float*>(_aligned_malloc( sizeof(float)*dataLen, 32 ));
float *buf2 = reinterpret_cast<float*>(_aligned_malloc( sizeof(float)*dataLen, 32 ));
for(int i=0; i<dataLen; i++)
{
    buf1[i] = 1;
    buf2[i] = 1;
}
double timePassed;
int t = clock();
float sum = 0;
//=========================SSE CODE=====================================
__m128 *p1 = (__m128 *)buf1;
__m128 *p2 = (__m128 *)buf2;
__m128 _result = _mm_set_ps1(0.0f);

for(int j=0;j<10000; j++)
{   
    p1 = (__m128 *)buf1;
    p2 = (__m128 *)buf2;        
    _result = _mm_sub_ps(_mm_set_ps(j,0,0,0) ,_result);

    for(int i=0; i<dataLen/4; i++)
    {
        _result = _mm_add_ps(_mm_mul_ps(*p1, *p2), _result);
        p1++;
        p2++;
    }
}

sum = _result.m128_f32[0]+_result.m128_f32[1]+_result.m128_f32[2]+_result.m128_f32[3];
timePassed = clock() - t;
std::cout<<std::fixed<<"SSE calculate result : "<<sum<<std::endl;
std::cout<<"SSE time used: "<<timePassed<<"ms"<<std::endl;

//=========================AVX CODE=====================================
t = clock();
__m256  *pp1 ; 
__m256  *pp2 ; 
__m256 _rresult = _mm256_setzero_ps();
sum = 0;

for(int j=0;j<10000; j++)
{   
    pp1 = (__m256*) buf1;
    pp2 = (__m256*) buf2;
    _rresult = _mm256_sub_ps(_mm256_set_ps(j,0,0,0,0,0,0,0), _rresult);

    for(int i=0; i<dataLen/8; i++)
    {       
        _rresult = _mm256_add_ps(_mm256_mul_ps(*pp1, *pp2), _rresult);
        pp1++;
        pp2++;
    }
}

sum = _rresult.m256_f32[0]+_rresult.m256_f32[1]+_rresult.m256_f32[2]+_rresult.m256_f32[3]+_rresult.m256_f32[4]+_rresult.m256_f32[5]+_rresult.m256_f32[6]+_rresult.m256_f32[7];
timePassed = clock() - t;
std::cout<<std::fixed<<"AVX calculate result : "<<sum<<std::endl;
std::cout<<"AVX time used: "<<timePassed<<"ms"<<std::endl;

_aligned_free(buf1);
_aligned_free(buf2);

}

4

1 に答える 1

5

ループに算術命令が 2 つしかなく、負荷が 2 つあるため、おそらく帯域幅が制限されているだけです。キャッシュに収まるようにデータ セットのサイズを小さくすると、パフォーマンスに違いが見られるはずです (ロード帯域幅がはるかに大きくなり、キャッシュからのロードの待ち時間が短縮されるため)。

(また、タイミングの数値が非常に高いようです。リリース ビルドを使用していること、つまり最適化が有効になっていることを確認してください。そうしないと、結果が誤解を招く可能性があります。)

于 2013-08-30T10:22:49.423 に答える