2014-09-25 3 views
1

У меня есть два ße целых чисел, которые я задаю его следующим образом:в случайном порядке между SSE целочисленных регистрами

__m128i m1 = _mm_set_epi32(4,3,2,1); 
    __m128i m2 = _mm_set_epi32(40,30,20,10); 

Теперь я должен сделать некоторые перетасовать между этими двумя регистрами и сохранить результат в других два регистре таким образом, что выход будет следующим:

 m3 = (30,3,10,1); 
    m4 = (40,4,20,2); 

Есть ли способ, которым я могу это достичь!

Благодаря

+0

Но я хочу сделать с ße перетасовки –

+0

@MarcoA. Это используется для перетасовки в одном регистре ... Я хочу перетасовать между двумя регистрами –

+0

Правильно, извините. Я должен был внимательно прочитать –

ответ

2

Вы можете сделать это так:

t1 = _mm_shuffle_epi32(m1, 0xd8); 
t2 = _mm_shuffle_epi32(m2, 0xd8);  
m4 = _mm_unpackhi_epi32(t1,t2); 
m3 = _mm_unpacklo_epi32(t1,t2); 

Вот полный пример

#include <x86intrin.h> 
#include <stdio.h> 

int main() { 
     __m128i m1 = _mm_set_epi32(4,3,2,1); 
     __m128i m2 = _mm_set_epi32(40,30,20,10); 

     __m128i m3, m4, t1, t2; 
     t1 = _mm_shuffle_epi32(m1, 0xd8); 
     t2 = _mm_shuffle_epi32(m2, 0xd8);  
     m4 = _mm_unpackhi_epi32(t1,t2); 
     m3 = _mm_unpacklo_epi32(t1,t2); 

     int out3[4], out4[4]; 
     _mm_store_si128((__m128i*)out3, m3); 
     _mm_store_si128((__m128i*)out4, m4); 
     printf("%d %d %d %d\n", out3[3], out3[2], out3[1], out3[0]); 
     printf("%d %d %d %d\n", out4[3], out4[2], out4[1], out4[0]); 
} 

Выход

30 3 10 1 
40 4 20 2 
+1

вы сделали мой день ... спасибо u so much –

+0

BTW 0xd8 = 3120 в базе-4 (и 11011000 в двоичном формате). Это говорит вам, какие номера я меняю. Я знаю, что базовый 4 не типичен для размышлений, но в этом случае это удобно. –

1

я придумал несколько иной решение для Z Boson:

#include <emmintrin.h> 
#include <iostream> 
#include <cstring> 

void print_data(const char *name, __m128i v) 
{ 
    struct { int a, b, c, d; } unpacked; 

    std::memcpy((void *)&unpacked, (void *)&v, sizeof(v)); 
    std::cout << name << ":"; 
    std::cout << unpacked.d << " " << unpacked.c << " " 
      << unpacked.b << " " << unpacked.a << std::endl; 
} 

int main() 
{ 

    __m128i m1 = _mm_set_epi32(4,3,2,1); 
    __m128i m2 = _mm_set_epi32(40,30,20,10); 
    __m128i mask = _mm_set_epi32(-1,0,-1,0); 

    /* 
    m3 = (30,3,10,1); 
    m4 = (40,4,20,2); 
    */ 

    __m128i tmp1 = _mm_shuffle_epi32(m2, 0x80); 
    __m128i tmp2 = _mm_shuffle_epi32(m1, 0x31); 
    __m128i m3 = _mm_or_si128(_mm_and_si128(mask, tmp1), _mm_andnot_si128(mask, m1)); 
    __m128i m4 = _mm_or_si128(_mm_and_si128(mask, m2), _mm_andnot_si128(mask, tmp2)); 

    print_data("m3", m3); 
    print_data("m4", m4); 
} 

Я уверен, что распаковывать вариант немного лучше ...

Смежные вопросы