2013-03-13 6 views
5

Я ищу самый быстрый способ проверить, содержит ли регистр 128 NEON все нули, используя NEON intrinsics. настоящее время я использую 3 или операции, и 2 MOVs:Самый быстрый способ протестировать 128-битный регистр NEON для значения 0 с использованием встроенных функций?

uint32x4_t vr = vorrq_u32(vcmp0, vcmp1); 

uint64x2_t v0 = vreinterpretq_u64_u32(vr); 
uint64x1_t v0or = vorr_u64(vget_high_u64(v0), vget_low_u64(v0)); 

uint32x2_t v1 = vreinterpret_u32_u64 (v0or); 
uint32_t r = vget_lane_u32(v1, 0) | vget_lane_u32(v1, 1); 

if (r == 0) { // do stuff } 

Это переводит на GCC на следующий код сборки:

VORR  q9, q9, q10 
VORR  d16, d18, d19 
VMOV.32 r3, d16[0] 
VMOV.32 r2, d16[1] 
VORRS r2, r2, r3 
BEQ  ... 

Кто-нибудь иметь представление о более быстрый способ?

ответ

1

Вы, кажется, ищет и встроенных функций это путь: ответ

inline bool is_zero(int32x4_t v) noexcept 
{ 
    v = v == int32x4{}; 

    return !int32x2_t(
    vtbl2_s8(
     int8x8x2_t{ 
     int8x8_t(vget_low_s32(v)), 
     int8x8_t(vget_high_s32(v)) 
     }, 
     int8x8_t{0, 4, 8, 12} 
    ) 
)[0]; 
} 

Nils Pipenbrinck имеет недостаток в том, что он принимает на себя контроль качества, кумулятивный флаг насыщения, чтобы быть ясным.

6

Хотя этот ответ может быть немного поздно, есть простой способ сделать тест только 3 инструкции и без каких-либо дополнительных регистров:

inline uint32_t is_not_zero(uint32x4_t v) 
{ 
    uint32x2_t tmp = vorr_u32(vget_low_u32(v), vget_high_u32(v)); 
    return vget_lane_u32(vpmax_u32(tmp, tmp), 0); 
} 

Возвращаемое значение будет отлично от нуля, если какой-либо бит в 128 -битный регистр NEON.

2

Если вы ориентируетесь AArch64 NEON, вы можете использовать следующее, чтобы получить значение для тестирования с помощью всего две инструкции:

inline uint64_t is_not_zero(uint32x4_t v) 
{ 
    uint64x2_t v64 = vreinterpretq_u64_u32(v); 
    uint32x2_t v32 = vqmovn_u64(v64); 
    uint64x1_t result = vreinterpret_u64_u32(v32); 
    return result[0]; 
} 
0

Если у вас есть AArch64 вы можете сделать это еще проще. У них есть новая инструкция, предназначенная для этого.

inline uint32_t is_not_zero(uint32x4_t v) 
{ 
    return vaddvq_u32(v); 
} 
+0

Это кажется уязвимым для переполнения. – wolfv

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

  • Нет связанных вопросов^_^