2016-02-12 2 views
2

Я пытаюсь передать SSE-функцию, которая получает абсолютную разницу в двух 8-разрядных целых массивах без знака. Это выглядит следующим образом:Altivec: аналог _mm_sad_epu8()

uint64_t AbsDiffSum(const uint8_t * a, const uint8_t * b, size_t size) 
{ 
    assert(size%16 == 0); 
    __m128i _sum = _mm_setzero_si128(); 
    for(size_t i = 0; i < size; i += 16) 
    { 
     const __m128i _a = _mm_loadu_si128((__m128i*)(a + i)); 
     const __m128i _b = _mm_loadu_si128((__m128i*)(b + i)); 
     _sum = _mm_add_epi64(_sum, _mm_sad_epu8(_a, _b)); 
    } 
    return _mm_cvtsi128_si64(_mm_add_epi64(_sum, _mm_srli_si128(_sum, 8))); 
} 

Основная работа выполняется по внутренней функции _mm_sad_epu8().

Есть ли аналог для Altivec?

ответ

3

К сожалению, нет прямого аналога встроенной функции _mm_sad_epu8 для Altivec. Но есть возможность подражать ему:

typedef __vector uint8_t uint8x16_t; 
typedef __vector uint32_t uint32x4_t; 
const uint8_t K8_01 = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 

uint64_t AbsDiffSum(const uint8_t * a, const uint8_t * b, size_t size) 
{ 
    uint32x4_t _sum = {0, 0, 0, 0}; 
    for(size_t i = 0; i < size; i += 16) 
    { 
     // Aligned loading of 128-bit vector 
     uint8x16_t _a = vec_ld(a + i); 
     // Aligned loading of 128-bit vector 
     uint8x16_t _b = vec_ld(b + i); 
     // Find absolute difference of two 8-bit unsigned 
     uint8x16_t absDifference = vec_sub(vec_max(a, b), vec_min(a, b)); 
     // Sum result with using of vec_msum 
     _sum = vec_msum(absDifference, K8_01, _sum); 
    } 
    return vec_extract(_sum, 0) + vec_extract(_sum, 1) + 
      vec_extract(_sum, 2) + vec_extract(_sum, 3); 
} 
+0

Спасибо. Это работает. – Georg

+0

Почему вы используете переменные с ведущими '_' в своих именах? Это просто вызывает проблемы, так как эти имена зарезервированы для конкретных приложений. 'vec_ld' может быть макросом, который внутренне использует временное имя' _a' или что-то в этом роде. –

+0

Я знаю, что имена, такие как __abc и _Abc, зарезервированы для целей компилятора. Такие имена, как _abc, могут использоваться бесплатно. В текущем случае я использовал имитационные имена для скалярных и векторных переменных. – ErmIg