CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

which is faster, direct division or alternate

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
darryl_co



Joined: 11 Nov 2015
Posts: 21
Location: India

View user's profile Send private message

which is faster, direct division or alternate
PostPosted: Sat Mar 12, 2016 2:14 am     Reply with quote

If I need to divide a variable by 3, which of the two methods are faster and preferable while writing code
1) x/3
OR
2) x/2-x/4 x/8-x/16 x/32-x/64
Also how to find the time or number of cycles taken for such functions?
Ttelmah



Joined: 11 Mar 2010
Posts: 19452

View user's profile Send private message

PostPosted: Sat Mar 12, 2016 3:25 am     Reply with quote

What _type_ is the variable?.
What PIC are you using?.

It matters.

On timings, just time it. Either use the MPLAB simulator, or pulse a pin when you enter the function and come out.

There is a list of the times that divisions, multiplications etc., take in the manual. Under 'frequently asked questions'. These are for standard clock rates, but can be easily scaled to suit your clock rate.

Now, for DSPIC's, there is a hardware integer division, so /3 will be faster than using separate divisions.
On a float, it'll be faster to multiply by 0.3333 (a single multiplication is always faster than division).

Assuming an integer like int16, the sequence required is x/4 +x/16 +x/64 + x/256 + x/1024....., not your /2 etc...

Now the problem is that if you did this as x/4 +x/16 etc., this would involve loading 'x' and rotating it more and more it each time. However if you use a temporary variable, you can avoid having to repeat the rotations, and (of course) if you only need a limited accuracy, something like three or four terms might be adequate. 4 terms would give 0.33203125*, which on an int16, would only differ by less than a hundred, on the largest possible starting number (65535). or include /1024, and get 0.3330078125*, and might well be accurate enough for 99% of applications. So you could then save a lot over the default maths (which goes out to all 16 terms for an int16).
temtronic



Joined: 01 Jul 2010
Posts: 9205
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Mar 12, 2016 3:29 pm     Reply with quote

How about (X*6) /2 ?
Multiplying is faster than odd division, and /2 is a single rotate ,also very fast.
Might be worth a try, look at code in listing,see what happens.

Jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Mar 12, 2016 5:21 pm     Reply with quote

x=9
x/3=3

vs
(x*6)/2 which simplifies to just (x*3) by rearrangement
(9*6)/2=27

not even sure if its faster - but that's beside the point - it is merely wrong

Very Happy Very Happy Very Happy Rolling Eyes Rolling Eyes Rolling Eyes
temtronic



Joined: 01 Jul 2010
Posts: 9205
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Mar 12, 2016 5:45 pm     Reply with quote

hmm that's what I get for running over my own foot with a forklift then trying to 'take my mind' off that mistake...
somehow it seemed 'right'.....
off to get some heavy duty meds....

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19452

View user's profile Send private message

PostPosted: Sun Mar 13, 2016 2:43 am     Reply with quote

Ouch....

We all get days like that, when you just 'click' onto the wrong line. Often then loads of things go wrong at once. Hope you have had your 'threesome' (if you believe these 'come in threes'...).

However, the multiply and binary divide solution, though 'got wrong' this time, is a good way to go. A 'classic' with an int16 (for example), would be to cast to an int32, and multiply by 21845. Then just take the top two bytes of the result (/65536). This is only faster on a PIC18, but on these is about 30% quicker than the int16 division. The reason it gains on the PIC18, is the hardware multiply. * on a PIC18, is about 7* faster than the same multiplication on a PIC16.

Generically solving by multiplication, then /256, or /65536, is a very good way to go. I did a servo system some time ago, and like all PID or similar servos, you have factors for each of the terms, like 0.17 etc.. Wanting the maximum speed, I treated the system values as int24, with these available via a union, to access the upper int16. Wrote int24 maths routines. Then the factors were stored '*256'. Effectively it became fixed point arithmetic, with the top 16 bits being the integer part and the bottom 8 bits the fraction.
darryl_co



Joined: 11 Nov 2015
Posts: 21
Location: India

View user's profile Send private message

Single Multiplication
PostPosted: Sun Mar 13, 2016 8:06 am     Reply with quote

Thanks Ttelmah, I had come across that maths calculations time but did not bookmark it and was searching on google but didn't find it. Thanks to you, I finally found it. As per your suggestions, I think X*0.3333 would be better than (X*6)/2. Faster to have one multiplication than multiply than divide.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 13, 2016 9:18 am     Reply with quote

Quote:
Also how to find the time or number of cycles taken for such functions?

This post explains how to use the MPLAB (vs. 8.92) Stopwatch feature
to find out how many cycles (and microseconds) it takes to execute a
block of code:
http://www.ccsinfo.com/forum/viewtopic.php?t=38351
darryl_co



Joined: 11 Nov 2015
Posts: 21
Location: India

View user's profile Send private message

PostPosted: Sun Mar 13, 2016 10:13 am     Reply with quote

PCM programmer wrote:
Quote:
Also how to find the time or number of cycles taken for such functions?

This post explains how to use the MPLAB (vs. 8.92) Stopwatch feature
to find out how many cycles (and microseconds) it takes to execute a
block of code:
http://www.ccsinfo.com/forum/viewtopic.php?t=38351

Thanks user PCM Programmer.
One thing that I have understood is that if possible avoid maths calculations and use lookup table with pre calculated values.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Mar 14, 2016 5:02 am     Reply with quote

One other thing to think about is that if you are really concerned about the timing of basic arithmetic operations, then that's a warning flag that you are not doing things the best way.

Optimising arithmetic, and things like FAST_IO is often pointless, or at least doesn't give the speed improvement you need. Often the way to improve speed is to look at how your code is doing things: optimise the algorithm and structure rather than the operations/instructions.

Some people seem obsessed with raw speed, as if its the only thing that matters (look at the number of posters that come on here with #use FAST_IO without understanding how and why it should be used. Hint: I've NEVER used it/needed to use it). It was always so, I remember most freshers at uni being equally obsessed thirty plus years ago (I had already got it out of my system while at school).

I'm not saying speed isn't sometimes important. I'm saying that worrying about whether an integer division is as fast as it could be is generally not a productive way to produce efficient code. And as has been pointed out, it all depends: such optimisations are not general and may well actually be slower when used in situations they were not intended for.
Ttelmah



Joined: 11 Mar 2010
Posts: 19452

View user's profile Send private message

PostPosted: Mon Mar 14, 2016 5:27 am     Reply with quote

darryl_co wrote:
PCM programmer wrote:
Quote:
Also how to find the time or number of cycles taken for such functions?

This post explains how to use the MPLAB (vs. 8.92) Stopwatch feature
to find out how many cycles (and microseconds) it takes to execute a
block of code:
http://www.ccsinfo.com/forum/viewtopic.php?t=38351

Thanks user PCM Programmer.
One thing that I have understood is that if possible avoid maths calculations and use lookup table with pre calculated values.


Um. Depends what you are really doing.

For 99% of code, FP maths is not wanted/needed. It is worth understanding that FP, is a way of handling a wide _range_ of numbers, but at a cost in accuracy and speed. Now most control applications do not have such a 'range'. The ADC for example, only handles input voltages over it's Vref+ to Vref- range, and actually gives results from 0 to 1024. We so commonly see people posting using:

Vout=adc_val * 5.0/1023

As a way of displaying 'volts', without realising that they could actually get a better result, faster, using scaled integers. Better, for two reasons (1023 is wrong, and this is also not handling the small offset that is in the real conversion). Faster - well it just is. Not only in the actual calculation, but in everything done with it afterwards.

Now, there are PIC applications that do need FP (for instance I have one system where a logarithmic scaling over a very wide range is required), but most of the time, using FP in a control system, is a sign of not really sitting down and thinking about what is really needed.
temtronic



Joined: 01 Jul 2010
Posts: 9205
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Mar 14, 2016 5:42 am     Reply with quote

I think most that post here are 'floating point' oriented. ALL the math I ever did in schools was FP though, I only ever had 3 short courses in 'computers'. It'd be interesting to know IF 'scaled integer' math is ACTUALLY taught in school computer courses these days. I'm thinking even the profs never heard of it !

Jay
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Mar 14, 2016 6:07 am     Reply with quote

temtronic wrote:
It'd be interesting to know IF 'scaled integer' math is ACTUALLY taught in school computer courses these days. I'm thinking even the profs never heard of it !


It wasn't when I was at university in the early eigthies, and certainly not at school level! It was something most of my professors had more than heard about and were well glad to see the back of, associating it with pre-FP hardware days when pretty much everything was done with scaled integers.

My first DSP application was FFT based on a TMS32010, and I did that with block scaled sixteen bit integers and interstage scaling. I even built my sine table with integers, with a little known error. I didn't know for sure until over a decade later I did Excel and double length FP versions on the PC. The errors associated with my previous integer implementation was so small as to be negligable.

I am not averse to the odd FP calculation here and there, especially with ADC scaling, as ADC volts are rarely, if ever useful to me. I scale directly into relevant engineering units avoiding dividing. Generally it needs just one FP multiply; any offsetting I do in integers. I do not scale each and every ADC conversion. I also only scale to engineering units when absolutely I need to, any averaging and filtering being done on the raw ADC counts in integers. Basically, I avoid doing anything over and over again that my code has to do only once.
Ttelmah



Joined: 11 Mar 2010
Posts: 19452

View user's profile Send private message

PostPosted: Mon Mar 14, 2016 9:55 am     Reply with quote

'Fixed point', is quite common, but not at 'school level'. With the preponderance of the PC, with it's hardware floating point processor, lots of courses take the easy way out and stick to floating point.

However once you get involved in DSP, financial calculations etc., there is a switch to fixed point maths.
Microsoft used to do a library for this, and things like SQL, have a 'decimal money' type. Accountants are taught to avoid float, and work either in a specifically 'financial' type, or use integer 'cents' (or pence etc.).

There are some very nice fixed point libraries for C, and I've been tempted in the past to port these to CCS, but never seem to have the time.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group