|
|
View previous topic :: View next topic |
Author |
Message |
darryl_co
Joined: 11 Nov 2015 Posts: 21 Location: India
|
which is faster, direct division or alternate |
Posted: Sat Mar 12, 2016 2:14 am |
|
|
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: 19552
|
|
Posted: Sat Mar 12, 2016 3:25 am |
|
|
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: 9246 Location: Greensville,Ontario
|
|
Posted: Sat Mar 12, 2016 3:29 pm |
|
|
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
|
|
Posted: Sat Mar 12, 2016 5:21 pm |
|
|
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
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Sat Mar 12, 2016 5:45 pm |
|
|
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: 19552
|
|
Posted: Sun Mar 13, 2016 2:43 am |
|
|
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
|
Single Multiplication |
Posted: Sun Mar 13, 2016 8:06 am |
|
|
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
|
|
Posted: Sun Mar 13, 2016 9:18 am |
|
|
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
|
|
Posted: Sun Mar 13, 2016 10:13 am |
|
|
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
|
|
Posted: Mon Mar 14, 2016 5:02 am |
|
|
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: 19552
|
|
Posted: Mon Mar 14, 2016 5:27 am |
|
|
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: 9246 Location: Greensville,Ontario
|
|
Posted: Mon Mar 14, 2016 5:42 am |
|
|
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
|
|
Posted: Mon Mar 14, 2016 6:07 am |
|
|
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: 19552
|
|
Posted: Mon Mar 14, 2016 9:55 am |
|
|
'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. |
|
|
|
|
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
|