Pergunta sobre sse, avx, c – Como executar o deslocamento à esquerda do elemento com __m128i?

4

As instruções de mudança de SSE que encontrei só podem mudar na mesma quantia em todos os elementos:

_mm_sll_epi32()_mm_slli_epi32()

Estes deslocam todos os elementos, mas pelo mesmo valor de mudança.

Existe uma maneira de aplicar diferentes mudanças aos diferentes elementos? Algo assim:

__m128i a,  __m128i b;  

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

Sua resposta

3   a resposta
2

suas opções são limitadas. Se você pode controlar o formato do argumento de contagem de turnos, então você pode usar_mm_mullo_pi16 já que multiplicar por um poder de dois é o mesmo que mudar por esse poder.

Por exemplo, se você quiser deslocar seus 8 elementos de 16 bits em um registrador SSE<0, 1, 2, 3, 4, 5, 6, 7> você pode multiplicar por 2 aumentados para os poderes de contagem de turnos, ou seja, por<0, 2, 4, 8, 16, 32, 64, 128>.

Obrigado, eu consegui por _mm_mullo_epi32 (SSE4.1). Hmm ..., pode haver uma maneira melhor para a CPU da Intel? user1468756
7

_mm_shl_epi32() intrínseco que faz exatamente isso.

http://msdn.microsoft.com/pt-br/library/gg445138.aspx

No entanto, requer aConjunto de instruções XOP. Somente os processadores AMD Bulldozer e Interlagos ou mais tarde têm essa instrução. Não está disponível em nenhum processador Intel.

Se você quiser fazer isso sem as instruções do XOP, você precisará fazê-lo da maneira mais difícil: Retire-as e faça-as uma a uma.

Sem instruções XOP, você pode fazer isso com o SSE4.1 usando os seguintes intrínsecos:

_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

Eles permitirão que você extraia partes de um registrador de 128 bits em registradores regulares para fazer a mudança e colocá-los de volta.

Se você for com o último método, será horrivelmente ineficiente. É por isso_mm_shl_epi32() existe em primeiro lugar.

0

em algumas circunstâncias, isso pode substituir_mm_shl_epi32(a, b):

_mm_mullo_ps(a, 1 << b);

de um modo geral, isso requerb ter um valor constante - não sei de uma maneira eficiente de calcular(1 << b) usando instruções SSE mais antigas.

Perguntas relacionadas