Interesting thoughts.
I think its time to do some bare bones code to see which works out to be quicker.
Bill.
Interesting thoughts.
I think its time to do some bare bones code to see which works out to be quicker.
Bill.
Hi Guys,
So I finally got some time to do some testing.
I have an admission to make - the 60uS I was seeing that started this whole process off seemed to be caused by failing to set my debug output that was watched with the logic analyser to a known state if the values didn't match...
What I did yesterday was run a few different comparison scenarios to see what sort of timing you got. Remember this is a 16f1933 running at 32Mhz, so instruction time is about 0.5us.
What I am doing is comparing the address I want to grab with the current position in the incoming data stream. I reset a counter when I see a header and then count each data packet coming in. When the address matches the count I receive the next three values into a buffer that the main code loop processes. The address can be a value from 1 - 512 so I need to use word variables.
Doing an if..then compare with two word variables takes 5.125 us
Doing an if..then highbyte and lowbyte compare takes 2.125usCode:dbg_out = 1 ' set my debug line high for timing test if current_position = current_add then ' do the buffer loading endif dbg_out = 0
Code:dbg_out = 1 ' set my debug line high for timing test if current_position.highbyte = current_add.highbyte then ' 2.125 us if current_position.lowbyte = current_add.lowbyte then ' do the buffer loading endif endif dbg_out = 0
Doing an XORNOT compare takes 4.125us
Code:dbg_out = 1 ' set my debug line high for timing test if (current_position XORNOT current_add) then ' do the buffer loading endif dbg_out = 0
Doing an XORNOT Lowbyte Highbyte compare takes 7.625us
So it looks like Darell was correct that the fastest way is a If..Then with Lowbyte / Highbyte.Code:dbg_out = 1 ' set my debug line high for timing test if (current_position.highbyte XORNOT current_add.highbyte) then if (current_position.lowbyte XORNOT current_add.lowbyte) then ' do the buffer loading endif endif dbg_out = 0
Bill.
Last edited by bcd; - 22nd April 2010 at 02:08. Reason: Put the correct CODE demarkers in.
In the comparissons you have made, were the two variables (either word or byte) equal?
That is important in your second case with the two If-Then's. In case the first if-then fails it will exit sooner.
Ioannis
Last edited by Ioannis; - 22nd April 2010 at 11:36.
Ioannis has a point (but maybe not the one I initially thought he was making... ).
What about:
if (a.highbyte xornot b.highbyte) and (a.lowbyte xornot b.lowbyte) then
' do stuff
endif
This removes an if-then macro/template from the timing equation.
You will always be making two comparisons to confirm equality, but there will be an overhead of potentially one unneccessary compare when a and b are not equal (but, hey, at least you know for sure how fast the code operates)
I'm sort of attached to xornot now...don't want to let it go...
Phil.
and I wish I had a stickfigure that did the 'dance of the happy programmer'![]()
Duck sensing headlights! Quack, quack, Bing!
The separate IF/THEN "templates" make it quicker.
When you have multiple AND's/OR's/XORNOT's etc. on the same line, then intermediate variables (T1+) are used to keep track of each "Term".
And T1+ variables are WORDs (LONGs for PBPL).
So while it looks shorter in the code listing, it really takes longer.<hr>
Well, I was trying to keep it straight PBP.
Which is why the previous example only got a "FASTer" rating.
But, if you want the "FASTest", ya gotta drop down to ASM with bank0/system variables.
Of course, someone will probably find a "FASTest.er" way ... I hope.Code:val1 VAR WORD BANK0 SYSTEM val2 VAR WORD BANK0 SYSTEM ASM movf val1+1, W subwf val2+1, W btfss STATUS, Z goto NotEqual movf val1, W subwf val2, W btfss STATUS, Z goto NotEqual L?GOTO _UserRoutine ; val1 = val2 NotEqual ENDASM UserRoutine: ;... yadda yadda ...<hr>
ADDED:
The above can only be used once without modification.
But if you turn it into a Macro, it can be used multiple times, with different variables. (as long as they're in bank0)
hth,Code:val1 VAR WORD BANK0 SYSTEM val2 VAR WORD BANK0 SYSTEM ASM DT_EQUAL macro v1, v2, label local NotEqual movf v1+1, W subwf v2+1, W btfss STATUS, Z goto NotEqual movf v1, W subwf v2, W btfss STATUS, Z goto NotEqual L?GOTO label ; v1 = v2 NotEqual endm ENDASM ;--- usage ------------------------- @ DT_EQUAL val1, val2, _UserRoutine ; IF val1 = val2 THEN UserRoutine UserRoutine: ;... yadda yadda ...
Last edited by Darrel Taylor; - 23rd April 2010 at 02:24. Reason: ADD: macro
DT
Darrel,
Using the same way, (or a similar logic) can it be done to compare two words whether they are smaller or bigger?
Highy byte can always be bigger but low byte can be smaller.
___________
"If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte
I now see that my question already has the answer in itself.
Just compare the high byte, skip comparing the low; so in fact no need to compare the whole word.
![]()
"If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte
Bookmarks