SIMD Comparaison result and use

hi,

when i do the diff

    // Compute diff
    int32x4_t diff1_4 = vabsq_s32(vsubq_s32(A, B));

I got 4 result. One for each test (A1,B1)(A2,B2)(A3,B3) and (A4,B4)

And than i have to do the comparaison

    uint32x4_t mask1_4 = vcltq_s32(diff1_4, X);

So in "uint32x4_t mask1_4" i got the comparaison for each test, so 4 résult.

the answer on post "SIMD help for exemple" was to use

    if (vmaxvq_u32(mask1_4) > 0) { ... }

I thinks my sentence was confuse in the previous post. I wrote  

   " if (mask1_4[0] > 0 && mask1_4[1] > 0)  and if (mask1_4[2] > 0 && mask1_4[3] > 0) "

but it is not    if(  mask1_4[0] > 0  &&  mask1_4[1] > 0  &&   mask1_4[2] > 0  &&  mask1_4[3] > 0) )

i need to do 2 test

   if (mask1_4[0] > 0 && mask1_4[1] > 0){

        process data1

   }

  if (mask1_4[2] > 0 && mask1_4[3] > 0){

      process data2

 }

I think that vmaxvq_u32(mask1_4) will check all the comparaison. like

    if(  mask1_4[0] > 0 && mask1_4[1] > 0  &&   mask1_4[2] > 0 && mask1_4[3] > 0  )

PS: i think i should have post it in the old post

Parents
  • t look like it is a problem of printf using signed and unsigned integer type.

    You need to use "%d" for signed and "%u" for unsigned.

    uint32x4_t mask1_4 = vcltq_u32(diff1_4, constseuil);

    In your original code your diff1_4 is signed and you were using "vcltq_s32" which is the signed compare, so the compare should be correct for signed values.

    The result of all of the NEON compare functions is not really meaningful as a number - it's just a bitmask with all bits in a lane set to 1 if the compare, like vcltq_s32, passed and zero if it failed. Given it's not expected to be interpreted as a number, the result is always uint32_t no matter what the original compare data type was, and the only comparison that matters is whether that mask is zero or non-zero.

Reply
  • t look like it is a problem of printf using signed and unsigned integer type.

    You need to use "%d" for signed and "%u" for unsigned.

    uint32x4_t mask1_4 = vcltq_u32(diff1_4, constseuil);

    In your original code your diff1_4 is signed and you were using "vcltq_s32" which is the signed compare, so the compare should be correct for signed values.

    The result of all of the NEON compare functions is not really meaningful as a number - it's just a bitmask with all bits in a lane set to 1 if the compare, like vcltq_s32, passed and zero if it failed. Given it's not expected to be interpreted as a number, the result is always uint32_t no matter what the original compare data type was, and the only comparison that matters is whether that mask is zero or non-zero.

Children
  • i just read your response when i was writting my. ;))

    sorry for the prévious post. I anderstoud the problem. Using %u rather than %d give me the response.

    it look like -1 is converted to unsigned int during the < -1

    so -1 = 4294967295 and -2 = 4294967294 so  4294967294 is  <  to 4294967295.

    but i is really confusing.

    Thanks very much for your answer. I was confuse at the begining of the day. Now i can go back to my program calmly, ;))

    have a good day.

  • sorry again, i just forgot to ask. what is the best in term of performance.

    extract and compare

    uint32x2_t mask1_4_01 = vget_low_u32(mask1_4); then  if ( vminv_u32(mask1_4_01) > 0)

    or

    if (mask1_4[0] > 0 && mask1_4[1] > 0 ){

    I think it is good for me then.

    and thanks again.