Forums

Check for overflow. Optimization issues in Blackfin compiler

Started by John McDermick February 18, 2011
Hello,

If I calculate a product P = x * y and I want to check that adding P
to a sum doesn't result in an overflow, is this the way to do it or is
there a more efficient way:


if (((sum ^ P) & MIN_32) == 0)
             {
                 if ((tmp ^ sum) & MIN_32)
                 {
                     tmp = (sum < 0) ? MIN_32 : MAX_32;
                     flagOverflow = 1;
                 }
             }

where tmp = sum + P



Also, I have been told that the blackfin compiler does a crappy job at
optimizing code which uses macros (macros for fixedpoint math). Is
there any truth in that statement? If so, why is that? And is the only
"workaround" not to use macros ?

Thank you




On 02/18/2011 02:35 PM, John McDermick wrote:
> Hello, > > If I calculate a product P = x * y and I want to check that adding P > to a sum doesn't result in an overflow, is this the way to do it or is > there a more efficient way: > > > if (((sum ^ P)& MIN_32) == 0) > { > if ((tmp ^ sum)& MIN_32) > { > tmp = (sum< 0) ? MIN_32 : MAX_32; > flagOverflow = 1; > } > } > > where tmp = sum + P
Do the addition in assembly, and check the overflow flag when you're done.
> Also, I have been told that the blackfin compiler does a crappy job at > optimizing code which uses macros (macros for fixedpoint math). Is > there any truth in that statement? If so, why is that? And is the only > "workaround" not to use macros ?
If the compiler (I assume you mean C) is even remotely compliant, then the macro expansion happens before the 'real compilation' starts. Any optimization problems then arise as a consequence of the contents of the macros, not the use of macros per se. C is just not a good fit with fixed point math. I can generally get a healthy speed up with a bunch of general-purpose assembly language functions, used as primitives and linked in with my C code. There's examples in my book, for the 32-bit x86 processors*; other processors are similar. http://www.wescottdesign.com/actfes/actfes.html * Not because I have any great love for the x86, but because it's the most likely machine for you to have on your desk, available for experimentation. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com Do you need to implement control loops in software? "Applied Control Theory for Embedded Systems" was written for you. See details at http://www.wescottdesign.com/actfes/actfes.html
John McDermick <johnthedspguy@gmail.com> wrote:
 
> If I calculate a product P = x * y and I want to check that adding P > to a sum doesn't result in an overflow, is this the way to do it or is > there a more efficient way:
I usually check for the wrong sign of the sum. (I presume this is signed arithmetic.) If you add numbers of opposite sign, it can't overflow. If the same sign, and the sum has the opposite sign, then it overflowed. For twos complement the test is that the carry into, and carry out of, the sign bit are different. Hard to do in C. -- glen

John McDermick wrote:

> Hello, > > If I calculate a product P = x * y and I want to check that adding P > to a sum doesn't result in an overflow, is this the way to do it or is > there a more efficient way: > > > if (((sum ^ P) & MIN_32) == 0) > { > if ((tmp ^ sum) & MIN_32) > { > tmp = (sum < 0) ? MIN_32 : MAX_32; > flagOverflow = 1; > } > } > > where tmp = sum + P
:)))))))) Pathetic. s32 x = FU; s32 y = BAR; s32 sum = x + y; u32 ovf =((((u32)x)>>31)+(((u32)y)>>31))^((((u32)sum)>>30)&0x02); ovf = ((ovf>>1)&(ovf^1))&1; And, of course, OVF could be impemented as a trivial inline function in assembler. > Also, I have been told that the blackfin compiler does a crappy job at
> optimizing code which uses macros (macros for fixedpoint math).
Which compiler? There are at least three different mainstream compilers for BlackFin: VDSP, GCC and GreenHills.
> Is > there any truth in that statement? If so, why is that? > And is the only > "workaround" not to use macros ?
Generic C integer math macros typically use binary shifts and type upconversions. They will be compiled exactly like that; i.e. into the type upconversions, operations on the higher types and shifts. This doesn't take advantage of the BlackFin instruction set which supports for the fractional math directly. So, you are encouraged to use built-in intrinsic functions for integer math where the performance matters. Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
John McDermick wrote:
> If I calculate a product P = x * y and I want to check that adding P > to a sum doesn't result in an overflow, is this the way to do it or is > there a more efficient way: > > if (((sum ^ P) & MIN_32) == 0) > { > if ((tmp ^ sum) & MIN_32) > { > tmp = (sum < 0) ? MIN_32 : MAX_32; > flagOverflow = 1; > } > }
I don't have my Blackfin compiler manuals at hand, but Blackfins support saturating arithmetic, and I'd expect there to be a macro for using it. I believe it is even possible to get the compiler to generate the summation in the 40-bit accumulator, so you could check for saturation at the very end.
> Also, I have been told that the blackfin compiler does a crappy job at > optimizing code which uses macros (macros for fixedpoint math). Is > there any truth in that statement? If so, why is that? And is the only > "workaround" not to use macros ?
That's probably a lot oversimplified. If you implement an 1.31 x 1.31 multiply in the portable way, #define mult_31_31(a,b) (((int64_t)(a) * (b)) >> 31) the resulting code will be worse than if you use the compiler builtin macro 'mult_fr1x32x32'. The mere use of macros doesn't make the code worse. My DSP code generally (contrary to MISRA rules) consists of tons of macros, defining arithmetic operations to the optimum builtins, assembler sequences or C expressions for all target architectures. Stefan