Вопрос по c, avx, sse – Как выполнить поэлементное смещение влево с помощью __m128i?

4

Инструкции по сдвигу SSE, которые я нашел, могут сдвигаться только на одну и ту же величину на всех элементах:

_mm_sll_epi32() _mm_slli_epi32()

Они сдвигают все элементы, но на одну и ту же величину.

Есть ли способ применить различные изменения к различным элементам? Что-то вроде этого:

__m128i a,  __m128i b;  

r0:=    a0  <<  b0;
r1:=    a1  <<  b1;
r2:=    a2  <<  b2;
r3:=    a3  <<  b3;

Ваш Ответ

3   ответа
2

Без XOP ваши возможности ограничены. Если вы можете контролировать формат аргумента подсчета сдвига, то вы можете использовать_mm_mullo_pi16 поскольку умножение на степень два равнозначно сдвигу на эту степень.

Например, если вы хотите сдвинуть свои 8 16-битных элементов в регистре SSE на<0, 1, 2, 3, 4, 5, 6, 7> Вы можете умножить на 2 повышенные до степени подсчета смены, т.е.<0, 2, 4, 8, 16, 32, 64, 128>.

Спасибо, я справился с этим с помощью _mm_mullo_epi32 (SSE4.1). Хм ... Может ли быть лучший способ для процессора Intel? user1468756
0

в некоторых случаях это может заменить_mm_shl_epi32(a, b):

_mm_mullo_ps(a, 1 << b);

вообще говоря, это требуетb иметь постоянное значение - я не знаю эффективного способа расчета(1 << b) используя более старые инструкции SSE.

7

Существует_mm_shl_epi32() свойственный именно это.

http://msdn.microsoft.com/en-us/library/gg445138.aspx

However, it requires the Набор инструкций XOP, Только AMD Bulldozer и Interlagos процессоры или более поздние имеют эту инструкцию. Это не доступно ни на одном процессоре Intel.

Если вы хотите сделать это без инструкций XOP, вам придется сделать это трудным путем: вытащите их и делайте их один за другим.

Без инструкций XOP вы можете сделать это с SSE4.1, используя следующие встроенные функции:

  • _mm_insert_epi32()
  • _mm_extract_epi32()

http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/intref_cls/common/intref_sse41_reg_ins_ext.htm

Это позволит вам извлечь части 128-битного регистра в обычные регистры, чтобы выполнить сдвиг, и вернуть их обратно.

Если использовать последний способ, он будет ужасно неэффективным. Вот почему_mm_shl_epi32() существует в первую очередь.

Похожие вопросы