64-битная специфическая SIMD встроенная - PullRequest
1 голос
/ 08 декабря 2010

Я использую следующее объявление объединения в SSE2.

typedef unsigned long uli;  
typedef uli v4si __attribute__ ((vector_size(16)));  
typedef union  
{  
    v4si v;  
    uli data[2];  
} uliv;  

uliv a, b, c;

Идея состоит в назначении двух переменных без знака (длиной 64 бита) каждому a и b, их XOR и размещении результата в c.

Явное назначение (a.data[0] = something) работает здесь, но требует больше времени.

Я планирую использовать встроенные функции.Если я использую _mm_set_epi64 (unsigned long x, unsigned long y), он запрашивает __m64 переменных.Если я приведу эти переменные (__m64)x, и все будет работать нормально, но это даст неверный результат.

for (k = 0; k < 10; k++)  
{  
    simda.v = _mm_set_epi64 (_mulpre1[u1][k], _mulpre2[u2][k]);  
    simdb.v = _mm_set_epi64 (res1[i+k], res2[i+k]);  
    simdc.v = _mm_xor_si128 (simda.v, simdb.v);  
}

Приведенный выше код выдает ошибку:

/usr/lib/gcc/x86_64-linux-gnu/4.4.3/include/emmintrin.h:578: note: expected ‘__m64’
but argument is of type ‘long unsigned int’

Не могли бы вы предложить несколько альтернатив (встроенных)?

1 Ответ

1 голос
/ 08 декабря 2010

Вы уверены , что unsigned long - это 64 бита в вашей системе?Возможно, безопаснее использовать unsigned long long или еще лучше uint64_t из <stdint.h>.

В моей системе _mm_set_epi64 принимает два unsigned long long параметра и возвращает __m128i.

Из вашего вопроса неясно, хотите ли вы просто (a) XOR два 64-битных значения или (b) XOR два вектора 2 x 64-битного значения?

Для случая (a) просто используйте скалярный код, например

uint64_t a, b, c;

c = a ^ b;

В случае (b) вам не нужны союзы и т.д., просто сделайте это:

__m128i va, vb, vc;

va = _mm_set_epi64(a1, a2);
vb = _mm_set_epi64(b1, b2);
vc = _mm_xor_si128(va, vb);
...