#175959 - sverx - Thu Mar 10, 2011 5:26 pm
    I guess I'm asking one of these things that they teach in high school but either I was sleeping or the school wasn't as good as I'd want it to be... BTW:
Do the integer divisions (and modulus) operations between a variable (the dividend) and a constant value, power of 2 [2^n] (the divisor) generate different ARM ASM code when the variable is unsigned vs. signed? And are the operations on the former faster?
Thanks :)
    
 
    #175960 - Dwedit - Thu Mar 10, 2011 11:47 pm
    Right shift is different depending on whether it's signed or not, so that the sign bit is preserved.  Otherwise, they are the same.  Doesn't matter whether you write x >> 4 or x/16, it's the same asm.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
    
 
    #175961 - Ruben - Fri Mar 11, 2011 5:48 am
    Dividing by a signed power of two needs a bit more baggage (cmp, addmi) to round the number to zero (ASR rounds to -infinity).
Read TONC ;D
    
 
    #175962 - sverx - Fri Mar 11, 2011 9:55 am
    Thank you both. If I understand correctly, if there's no real reason to use a signed, then it's better to use an unsigned, right? :)
    
 
    #175963 - Ruben - Fri Mar 11, 2011 10:07 am
    Mhm.
Here's the article at Cearn's site (turns out it wasn't TONC afterall =P): Linky
 | Quote: | 
  | ... There are some other consequences besides the obvious difference in results. First, there's how compilers deal with it. Compilers are very well aware that a bit-shift is faster than division and one of the optimizations they perform is replacing divisions by shifts where appropriate. For unsigned numerals the division will be replaced by a single shift. However, for signed variables some extra instructions have to added to correct the difference in rounding. | 
     
 
    #175964 - sverx - Fri Mar 11, 2011 10:44 am
    I went to run a test. For the work I needed to be done, the time required went from 22 scanlines down to 18 scanlines, after I changed my short ints with unsigned short ints. It's 18% faster :)
(Since I needed to store values from 0 to 4095 plus a 'null' value that I defined as '-1' I had to change that 'null' to 0xFFFF but anyway I see it was a good choice :) )
    
 
    #175965 - Ruben - Fri Mar 11, 2011 10:50 am
    Usually, you'll want to use 'signed int' or 'unsigned int' for types unless you ABSOLUTELY have to, but even then there's work arounds.
For example:
 | Code: | 
  | //! When doing addition/subtraction/storing //! You truncate only if you need to use multiplication/division
 0x6382 + 0xFF28 = 0x162AA [truncated to 16-bit, this is still correct]
 0x6382 - 0xFF28 = 0xF645A [ditto]
 
 //! When multiplying/dividing
 val <<= 16; //! get rid of carry area
 val >>= 16; //! shift back to 16-bit
 
 | 
     
 
    #175980 - sverx - Mon Mar 14, 2011 12:50 pm
    Thanks, I'll follow your advices :)