производительность SSE и AVX, когда ширина полосы памяти ограничена

В приведенном ниже коде я изменил «dataLen» и получил другую эффективность.

dataLen = 400 SSE время: 758000 долларов США AVX время: 483000 долларов США SSE> AVX

dataLen = 2400 SSE время: 4212000 сша AVX время: 2636000 сша SSE> AVX

dataLen = 2864 времени SSE: 6115000 долларов США, время AVX: 6146000 долларов США SSE ~ = AVX

dataLen = 3200 SSE время: 8049000 сша AVX время: 9297000 сша SSE <AVX

dataLen = 4000 SSE время: 10170000us AVX время: 11690000us SSE <AVX

Код SSE и AVX может быть упрощен следующим образом: buf3 [i] + = buf1 [1] * buf2 [i];

#include "testfun.h"
#include <iostream>
#include <chrono>
#include <malloc.h>
#include "immintrin.h"
using namespace std::chrono;

void testfun()
{
int dataLen = 4000; 
int N = 10000000;
float *buf1 = reinterpret_cast<float*>(_aligned_malloc(sizeof(float)*dataLen, 32));
float *buf2 = reinterpret_cast<float*>(_aligned_malloc(sizeof(float)*dataLen, 32));
float *buf3 = reinterpret_cast<float*>(_aligned_malloc(sizeof(float)*dataLen, 32));
for(int i=0; i<dataLen; i++)
{
    buf1[i] = 1;
    buf2[i] = 1;
    buf3[i] = 0;
}
//=========================SSE CODE=====================================
system_clock::time_point SSEStart = system_clock::now();
__m128 p1, p2, p3;

for(int j=0; j<N; j++)
for(int i=0; i<dataLen; i=i+4)
{
    p1 = _mm_load_ps(&buf1[i]);
    p2 = _mm_load_ps(&buf2[i]);
    p3 = _mm_load_ps(&buf3[i]);
    p3 = _mm_add_ps(_mm_mul_ps(p1, p2), p3);
    _mm_store_ps(&buf3[i], p3);
}

microseconds SSEtimeUsed = duration_cast<milliseconds>(system_clock::now() - SSEStart);
std::cout << "SSE time used: " << SSEtimeUsed.count() << " us, " <<std::endl;

//=========================AVX CODE=====================================
for(int i=0; i<dataLen; i++) buf3[i] = 0;

system_clock::time_point AVXstart = system_clock::now();
__m256  pp1, pp2, pp3; 

for(int j=0; j<N; j++)
for(int i=0; i<dataLen; i=i+8)
{       
    pp1 = _mm256_load_ps(&buf1[i]);
    pp2 = _mm256_load_ps(&buf2[i]);
    pp3 = _mm256_load_ps(&buf3[i]);
    pp3 = _mm256_add_ps(_mm256_mul_ps(pp1, pp2), pp3);
    _mm256_store_ps(&buf3[i], pp3);

}

microseconds AVXtimeUsed = duration_cast<milliseconds>(system_clock::now() - AVXstart);
std::cout << "AVX time used: " << AVXtimeUsed.count() << " us, " <<std::endl;

_aligned_free(buf1);
_aligned_free(buf2);
}

Мой процессор - Intel Xeon E3-1225 v2 с кэшем L1 32 КБ * 4 (4 ядра), при запуске этого кода используется только 1 ядро, поэтому используемый кэш L1 равен 32 КБ.

buf1 buf2 и buf3 достаточно малы для размещения в кэш-памяти L1 и кэш-памяти L2 (кэш-память L2 1 МБ). Оба SSE и AVX ограничены шириной полосы, но с увеличением dataLen. Почему AVX требуется больше времени, чем SSE?

Ответы на вопрос(2)

Ваш ответ на вопрос