Являются ли массивы векторов SIMD естественным образом неэффективны?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Являются ли массивы векторов SIMD естественным образом неэффективны?

Сообщение Anonymous »

Я компилирую код C ++ с MSVC. Мой пример кода ниже - SSE2, потому что я использую диспетчер, который означает, что Visual Studio не будет сбрасывать сборку для AVX или AVX512. Мой вариант использования - AVX2 и AVX512. < /P>
Я пробовал около 3 раза, чтобы использовать массивы векторов SIMD, чтобы заменить группы нагрузок и хранилища SIMD. Это заманчиво, но кажется ставкой присоски, потому что она никогда не ускоряет ситуацию, и, если что -то имеет тенденцию делать код медленнее. Это первый раз, когда я попытался посмотреть на сборку, для проекта, где код массива определенно медленнее, чем код загрузки/хранилища, и я был удивлен, увидев 13 инструкций по коду массива в зависимости от 8 для кода загрузки/хранилища, чтобы получить тот же результат. 8-line Block?

Являются ли массивы векторов SIMD естественным образом неэффективны по сравнению с эквивалентным кодом с использованием нагрузков/хранилищ с массивами фундаментальных типов данных? Или, может быть, просто компилятор MSVC не делает хорошую работу? Или, может быть, ответ отличается для массивов разных размеров в отношении проблем с кешем? Мои массивы SIMD обычно довольно маленькие, обычно около 200 удвоений. < /P>
< /li>
< /ol>
//__m128d* TR_vec = new __m128d[vec_arraysize];
//double* TR = (double*)TR_vec;
//const __m128d vec_dcp = _mm_set1_pd(dc_p);
//const __m128d vec_dcq = _mm_set1_pd(dc_q);

for (jj = bsteps - 1; jj > -1; jj--)
{
jjN = ((jj + 1) + vectorsize - 1) & (-vectorsize);
for (kk = 0; kk < jjN; kk += vectorsize)
{
#ifdef ARRAY_OF_SIMDS
vndx = kk >> 1;
TR_vec[vndx] = _mm_add_pd(_mm_mul_pd(vec_dcp, _mm_load_pd(TR + (kk + 1))), _mm_mul_pd(vec_dcq, TR_vec[vndx]));
#else
_mm_store_pd(TR + kk, _mm_add_pd(_mm_mul_pd(vec_dcp, _mm_load_pd(TR + (kk + 1))), _mm_mul_pd(vec_dcq, _mm_load_pd(TR + kk))));
#endif
}
}

//; 29161:
TR_vec[vndx] = _mm_add_pd(_mm_mul_pd(vec_dcp, _mm_load_pd(TR + (kk + 1))), _mm_mul_pd(vec_dcq, TR_vec[vndx]));

movaps xmm1, xmm7
mov rax, rcx
movaps xmm0, xmm6
mulpd xmm0, XMMWORD PTR [r8]
add rax, rax
add rdx, 2
add r8, 16
mulpd xmm1, XMMWORD PTR [rdi+rax*8]
mov rax, rcx
add rax, rax
addpd xmm1, xmm0
movups XMMWORD PTR [rdi+rax*8], xmm1
cmp rdx, r9

//; 29168:
_mm_store_pd(TR + kk, _mm_add_pd(_mm_mul_pd(vec_dcp, _mm_load_pd(TR + (kk + 1))), _mm_mul_pd(vec_dcq, _mm_load_pd(TR + kk))));

movaps xmm1, xmm6
movaps xmm0, xmm7
mulpd xmm1, XMMWORD PTR [rdi+rax*8+8]
mulpd xmm0, XMMWORD PTR [rdi+rax*8]
addpd xmm1, xmm0
movups XMMWORD PTR [rdi+rax*8], xmm1
add rax, 2
cmp rax, rcx
< /code>
//AVX2 dumped by Visual Studio:

TR_vec[vndx] = _mm256_add_pd(_mm256_mul_pd(vec_dcp, _mm256_load_pd(TR + (kk + 1))), _mm256_mul_pd(vec_dcq, TR_vec[vndx]));

mov rax, rcx
shl rax, 5
vmulpd ymm1, ymm5, YMMWORD PTR [rax+rdi]
movsxd rax, r8d
add r8d, 4
vmulpd ymm0, ymm4, YMMWORD PTR [rdi+rax*8]
mov rax, rcx
shl rax, 5
vaddpd ymm1, ymm0, ymm1
vmovupd YMMWORD PTR [rax+rdi], ymm1
cmp rdx, r9

_mm256_store_pd(TR + kk, _mm256_add_pd(_mm256_mul_pd(vec_dcp, _mm256_load_pd(TR + (kk + 1))), _mm256_mul_pd(vec_dcq, _mm256_load_pd(TR + kk))));

vmulpd ymm1, ymm5, YMMWORD PTR [rcx]
vmulpd ymm0, ymm4, YMMWORD PTR [rcx+8]
lea rcx, QWORD PTR [rcx+32]
vaddpd ymm1, ymm0, ymm1
vmovupd YMMWORD PTR [rcx-32], ymm1
sub rdx, 1


Подробнее здесь: https://stackoverflow.com/questions/797 ... nefficient
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»