Я пользуюсь vs2012 и хочу проверить работоспособность SSE и AVX.
Код для SSE и AVX практически одинаков,
кроме SSE использует _m128, а AVX использует _m256.
Я ожидал, что код AVX будет в два раза быстрее, чем код SSE,
Но результат теста показывает, что их скорость практически одинакова.
Я пытаюсь выбрать / 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);
}
Скорее всего, вы просто ограничены в пропускной способности, так как в вашем цикле только две арифметические инструкции и две нагрузки. Если вы уменьшите размер своего набора данных так, чтобы он помещался в кеше, вы должны увидеть разницу в производительности (так как у вас будет намного большая пропускная способность и меньшая задержка для нагрузок из кеша).
(Кроме того, ваши временные числа кажутся очень высокими — убедитесь, что вы используете сборку релиза, т.е. у вас включена оптимизация, иначе ваши результаты будут вводить в заблуждение.)
Других решений пока нет …