Motherboard Forums


Reply
Thread Tools Display Modes

Floating point vs fixed arithmetics (signed 64-bit)

 
 
kishor
Guest
Posts: n/a
 
      03-26-2012, 09:22 AM
Hi friends,
I am working on stellaris LM3s6965 (cortex-m3) & Keil 4.20 for data
acquisition. ADC
is signed 24-bit.

To perform software Gain calibration I have two options,

1. 64-bit fixed width arithmetic
uint16_t Gain; // 0x8000 means gain is 1
int32_t ADC_Reading; // It contains 24-bit signed integer ADC
reading

ADC_Reading = ((int64_t)ADC_Reading * Gain) / 0x8000; //
Gain calibration

// As multiplication of signed 24-bit & unsigned 16-bit will not fit
into 32-bit variable
// I typecast it to int64_t.

2. Single precision Float
float Gain;
int32_t ADC_Reading; // It contains 24-bit signed integer ADC
reading

ADC_Reading = ADC_Reading * Gain; // Gain
calibration

Which is better for performance wise.

Thanks,
Kishore.
 
Reply With Quote
 
 
 
 
Boudewijn Dijkstra
Guest
Posts: n/a
 
      03-26-2012, 10:08 AM
Op Mon, 26 Mar 2012 11:22:21 +0200 schreef kishor <(E-Mail Removed)>:
> Hi friends,
> I am working on stellaris LM3s6965 (cortex-m3) & Keil 4.20 for data
> acquisition. ADC is signed 24-bit.
>
> To perform software Gain calibration I have two options,
>
> 1. 64-bit fixed width arithmetic
> ADC_Reading = ((int64_t)ADC_Reading * Gain) / 0x8000;
> 2. Single precision Float
> ADC_Reading = ADC_Reading * Gain;
>
> Which is better for performance wise[?]


An (u)int64_t multiplication is always faster than a float multiplication,
assuming you don't have a hardware FPU.

Also, if you can deal with some loss of precision, you can pre-divide both
operands enough to be able to use 32-bit multiplication.


--
Gemaakt met Opera's revolutionaire e-mailprogramma:
http://www.opera.com/mail/
(Remove the obvious prefix to reply privately.)
 
Reply With Quote
 
 
 
 
Arlet Ottens
Guest
Posts: n/a
 
      03-26-2012, 11:14 AM
On 03/26/2012 11:22 AM, kishor wrote:
> Hi friends,
> I am working on stellaris LM3s6965 (cortex-m3)& Keil 4.20 for data
> acquisition. ADC
> is signed 24-bit.
>
> To perform software Gain calibration I have two options,
>
> 1. 64-bit fixed width arithmetic
> uint16_t Gain; // 0x8000 means gain is 1
> int32_t ADC_Reading; // It contains 24-bit signed integer ADC
> reading
>
> ADC_Reading = ((int64_t)ADC_Reading * Gain) / 0x8000; //
> Gain calibration


Cortex-M3 has a 32x32->64 bit multiply instruction, so if your compiler
is smart enough, it might use that. Check the generated assembly output.

If not, write your own assembly version.
 
Reply With Quote
 
David Brown
Guest
Posts: n/a
 
      03-26-2012, 11:24 AM
On 26/03/2012 13:14, Arlet Ottens wrote:
> On 03/26/2012 11:22 AM, kishor wrote:
>> Hi friends,
>> I am working on stellaris LM3s6965 (cortex-m3)& Keil 4.20 for data
>> acquisition. ADC
>> is signed 24-bit.
>>
>> To perform software Gain calibration I have two options,
>>
>> 1. 64-bit fixed width arithmetic
>> uint16_t Gain; // 0x8000 means gain is 1
>> int32_t ADC_Reading; // It contains 24-bit signed integer ADC
>> reading
>>
>> ADC_Reading = ((int64_t)ADC_Reading * Gain) / 0x8000; //
>> Gain calibration

>
> Cortex-M3 has a 32x32->64 bit multiply instruction, so if your compiler
> is smart enough, it might use that. Check the generated assembly output.
>
> If not, write your own assembly version.


Unless you require the absolutely fastest performance (and someone
asking the original question clearly is not - or he would already have
found the answer), do not write your own assembly code. It's just
pointless optimisation for optimisation's sake.

By all means, look at the generated assembly and see if it uses the
ideal instruction. If it doesn't, then file a report or support request
with the compiler supplier if you want.

Don't do inline assembly unless you really have a reason for it,
especially if you are not used to it.

 
Reply With Quote
 
kishor
Guest
Posts: n/a
 
      03-26-2012, 12:24 PM
Thanks for reply,

Compiler has generated "UMULL" instruction, (32-bit * 32-bit)
As it is signed multiplication it generated another three instructions.

Assembly listing is as below,

r1 - ADC_Reading (signed)
r2 - Gain (unsigned)

UMULL r0,r5,r1,r2 ; unsigned multiply 32 * 32
ASRS r3,r1,#31 ; Arithmetic Shift Right
MLA r2,r3,r2,r5 ; Multiply & Accumulate
MLA r1,r1,r12,r2 ; Multiply & Accumulate

MOV r2,#0x8000
MOV r3,r12

BL __aeabi_ldivmod ; 64-bits divider function

So multiplication is not a big deal. signed 64-bit divide takes time.

So still is it better than float?

Thanks,
Kishore.



 
Reply With Quote
 
Fredrik Ístman
Guest
Posts: n/a
 
      03-26-2012, 12:38 PM
>-----< kishor >
> So multiplication is not a big deal. signed 64-bit divide takes time.


You don't need the division. You need to shift down 31 bits to get back
to 32 bits.

Perhaps the ALU can do to all for you in one step. Check the compiler for
a built-in function for 32-bit signed fractional multiplication.

Read up on fractional arithmetic.

--
Fredrik ├ľstman
 
Reply With Quote
 
kishor
Guest
Posts: n/a
 
      03-26-2012, 01:33 PM
On Monday, March 26, 2012 6:08:00 PM UTC+5:30, Fredrik Ístman wrote:

> You don't need the division. You need to shift down 31 bits to get back
> to 32 bits.


I don't understand your point. In signed division we can't shift down bits simply.

> Perhaps the ALU can do to all for you in one step. Check the compiler for
> a built-in function for 32-bit signed fractional multiplication.
>
> Read up on fractional arithmetic.


Is there other method which avoids 64-bit division?


Kishore.
 
Reply With Quote
 
Arlet Ottens
Guest
Posts: n/a
 
      03-26-2012, 01:34 PM
On 03/26/2012 02:24 PM, kishor wrote:
> Thanks for reply,
>
> Compiler has generated "UMULL" instruction, (32-bit * 32-bit)
> As it is signed multiplication it generated another three instructions.
>
> Assembly listing is as below,
>
> r1 - ADC_Reading (signed)
> r2 - Gain (unsigned)
>
> UMULL r0,r5,r1,r2 ; unsigned multiply 32 * 32
> ASRS r3,r1,#31 ; Arithmetic Shift Right
> MLA r2,r3,r2,r5 ; Multiply& Accumulate
> MLA r1,r1,r12,r2 ; Multiply& Accumulate
>
> MOV r2,#0x8000
> MOV r3,r12
>
> BL __aeabi_ldivmod ; 64-bits divider function
>
> So multiplication is not a big deal. signed 64-bit divide takes time.
>
> So still is it better than float?


Try doing a >> 15 instead of a / 0x8000 in your C code.



 
Reply With Quote
 
David Brown
Guest
Posts: n/a
 
      03-26-2012, 01:45 PM
On 26/03/2012 15:33, kishor wrote:
> On Monday, March 26, 2012 6:08:00 PM UTC+5:30, Fredrik Ístman wrote:
>
>> You don't need the division. You need to shift down 31 bits to get
>> back to 32 bits.

>
> I don't understand your point. In signed division we can't shift down
> bits simply.


Correct.

But the compiler should do the strength reduction for you - take note of
the sign, do everything unsigned, then restore the sign. If it doesn't,
then check your optimisation settings and/or complain to the supplier.

>
>> Perhaps the ALU can do to all for you in one step. Check the
>> compiler for a built-in function for 32-bit signed fractional
>> multiplication.
>>
>> Read up on fractional arithmetic.

>
> Is there other method which avoids 64-bit division?
>


Yes - do everything unsigned. First think if the incoming data really
is signed - in most cases it is not. But if you have signed data (say
from a differential input), first note the sign then convert to a
positive value if needed. Then do your scaling and division (and if the
compiler can't convert an unsigned divide by 0x8000 to a shift, it's a
poor compiler - and you can do the shift by hand). Then restore the sign.

 
Reply With Quote
 
Arlet Ottens
Guest
Posts: n/a
 
      03-26-2012, 01:49 PM
On 03/26/2012 03:33 PM, kishor wrote:
> On Monday, March 26, 2012 6:08:00 PM UTC+5:30, Fredrik Ístman wrote:
>
>> You don't need the division. You need to shift down 31 bits to get back
>> to 32 bits.

>
> I don't understand your point. In signed division we can't shift down bits simply.


The difference is at most 1 LSB due to rounding differences, which is
probably less than your ADC noise.

You can make the difference even smaller by using a 32 bit gain variable.

You could also find out if ADC value is negative, reverse the sign,
perform unsigned arithmetic, and reverse the sign of the result.
 
Reply With Quote
 
 
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
TMS320F2812 Floating point vs fixed point speed? cman Embedded 2 03-10-2007 04:19 AM
floating point to fixed point conversion riya Embedded 7 02-24-2006 07:01 AM
Re: Floating point format for Intel math coprocessors CBFalconer Intel 0 06-27-2003 05:28 PM
Re: Floating point format for Intel math coprocessors Grant Edwards Intel 0 06-27-2003 03:34 PM
Re: Floating point format for Intel math coprocessors Dave Hansen Intel 0 06-27-2003 03:01 PM


All times are GMT. The time now is 07:07 AM.


Welcome!
Welcome to Motherboard Point
 

Advertisment