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
  • hi,

    vmaxv_u32() work fine. And i anderstoud the problem for >0 and < 0. It look like it is a problem of printf using signed and unsigned integer type. that is way i always see -1 for signed and unsigned.

    but i stil do not anderstand why if i use unsigned int.

    uint32x4_t mask1_4 = vcltq_u32(diff1_4, constseuil);

    the check is true for > 0 and at the same time == -2 and < -1. it is quite confusing.

    how unsigned can respond to == -2 and < -1.

    If i were using signed i would anderstand because signed check true for < 0, == -2 and < -1. wich is logic.

    do i miss one include in my program to avoid unsigned int to answer true to == -2 and < -1. for the == -2 i can, let said andertand. but for < -1 i do not. it is not logic that positive number can be inferieur at -1. It is the first time i see something like that. ;))

Reply
  • hi,

    vmaxv_u32() work fine. And i anderstoud the problem for >0 and < 0. It look like it is a problem of printf using signed and unsigned integer type. that is way i always see -1 for signed and unsigned.

    but i stil do not anderstand why if i use unsigned int.

    uint32x4_t mask1_4 = vcltq_u32(diff1_4, constseuil);

    the check is true for > 0 and at the same time == -2 and < -1. it is quite confusing.

    how unsigned can respond to == -2 and < -1.

    If i were using signed i would anderstand because signed check true for < 0, == -2 and < -1. wich is logic.

    do i miss one include in my program to avoid unsigned int to answer true to == -2 and < -1. for the == -2 i can, let said andertand. but for < -1 i do not. it is not logic that positive number can be inferieur at -1. It is the first time i see something like that. ;))

Children
  • 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.

  • 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.

  • I suspect they are going to end up exactly the same