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 CCS Technical Support

Slow compares with int16's

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



Joined: 21 Nov 2006
Posts: 129

View user's profile Send private message

Slow compares with int16's
PostPosted: Sat May 22, 2010 11:20 pm     Reply with quote

I'm trying to speed up a section of code, and noticed that the following surprised me with the number of instructions it involves:

Code:
if(first_variable > second_variable) third_variable = fourth_variable;


All variables in the example are int16's.

The list file:

Code:

07DFC:  BTFSC  x1B.7
07DFE:  BRA    7E26
07E00:  MOVLB  1
07E02:  MOVF   x9A,W
07E04:  MOVLB  8
07E06:  SUBWF  x1B,W
07E08:  BNC   7E26
07E0A:  BNZ   7E1C
07E0C:  MOVF   x1A,W
07E0E:  MOVLB  1
07E10:  SUBWF  x99,W
07E12:  BTFSS  FD8.0
07E14:  BRA    7E1A
07E16:  MOVLB  8
07E18:  BRA    7E26
07E1A:  MOVLB  8
07E1C:  MOVFF  19A,7D
07E20:  MOVFF  199,7C


Is there a faster way to do the compares? Or do they just really take that long to perform?
vinniewryan



Joined: 29 Jul 2009
Posts: 154
Location: at work

View user's profile Send private message MSN Messenger

PostPosted: Sun May 23, 2010 1:28 am     Reply with quote

That's just what it takes, as far as I know from how the condition works, it's comparing each bit from the highest of the int16 to the lowest, so it will compare each bit until it reaches the conclusion to the condition.

If firstvar is significantly greater than secondvar, it may be faster to use the following:

instead of:
if(first_variable > second_variable) //this should check each bit backwards until it reaches 'second_variable'

use:
if(second_variable < first_variable) //this should check each bit backwards until it reaches 'first variable'

Otherwise if you can use int8 instead of int16, it will also speed things up.
_________________
Vinnie Ryan
Ttelmah



Joined: 11 Mar 2010
Posts: 19505

View user's profile Send private message

PostPosted: Sun May 23, 2010 2:35 am     Reply with quote

It is basically 'what it takes'.
It doesn't do any form of bitwise comparison, it just performs a 16bit subtraction. However it is already quite efficient, in that lumps of the code are skipped if they "can't" apply.
Where you can save cycles, is in where the values are stored.
Nearly half the code, is basically switching banks to address the two values.
Two things apply. You will save a couple of instructions straight away, if the two values are in the same bank (declare them together). You can save more, by ensuring that they are in the bottom bank. Basically as a general 'layout' thing, declare the values which have the biggest effect on your code timing 'early' in your variable declarations. A search here, will find threads about the effect on speed of variable declaration order.

Best Wishes
sjb



Joined: 13 Apr 2010
Posts: 34
Location: UK

View user's profile Send private message

PostPosted: Sun May 23, 2010 2:48 am     Reply with quote

Well, I get...
Code:
....................    if(first_variable>second_variable)
00078:  MOVF   08,W
0007A:  SUBWF  06,W
0007C:  BNC   008E
0007E:  BNZ   0086
00080:  MOVF   05,W
00082:  SUBWF  07,W
00084:  BC    008E
....................       third_variable=fourth_variable;
00086:  MOVFF  0C,0A
0008A:  MOVFF  0B,09
.................... 

Which is shorted. I was just working with some 18F8722 code. would it depend on the processor/series.

EDIT:
But if I use signed int16 rather than int16 I get....
Code:
....................    if(first_variable>second_variable)
00078:  BTFSS  08.7
0007A:  BRA    0082
0007C:  BTFSS  06.7
0007E:  BRA    0094
00080:  BRA    0086
00082:  BTFSC  06.7
00084:  BRA    009C
00086:  MOVF   08,W
00088:  SUBWF  06,W
0008A:  BNC   009C
0008C:  BNZ   0094
0008E:  MOVF   05,W
00090:  SUBWF  07,W
00092:  BC    009C
....................       third_variable=fourth_variable;
00094:  MOVFF  0C,0A
00098:  MOVFF  0B,09
....................
Ttelmah



Joined: 11 Mar 2010
Posts: 19505

View user's profile Send private message

PostPosted: Sun May 23, 2010 7:20 am     Reply with quote

As I said, memory placement.
The big difference here, is that your two variables are adjacent, right at the bottom of memory.
So, if I simply declare two variables at the start of the code, placing them nice and low in memory, I get:
Code:

....................    if(first_variable > second_variable) third_variable = fourth_variable;
0024:  MOVF   07,W
0026:  SUBWF  05,W
0028:  BNC   003A
002A:  BNZ   0032
002C:  MOVF   04,W
002E:  SUBWF  06,W
0030:  BC    003A
0032:  MOVFF  0B,09
0036:  MOVFF  0A,08

However if I now locate 'first_variable' up to address 0x100, and 'second_variable' to 0x280, the code changes to:
Code:

....................    if(first_variable > second_variable) third_variable = fourth_variable;
0024:  MOVLB  2
0026:  MOVF   x81,W
0028:  MOVLB  1
002A:  SUBWF  x01,W
002C:  BNC   0048
002E:  BNZ   0040
0030:  MOVF   x00,W
0032:  MOVLB  2
0034:  SUBWF  x80,W
0036:  BTFSS  FD8.0
0038:  BRA    003E
003A:  MOVLB  1
003C:  BRA    0048
003E:  MOVLB  1
0040:  MOVFF  07,05
0044:  MOVFF  06,04

As I said, nearly half the code, is involved in handling bank switching, because of the location of the variables.
If you move the variables so they are adjacent (0x280, and 0x282), though not 'quite' as good as the version with them right at the bottom of memory, you get:
Code:

0024:  MOVLB  2
0026:  MOVF   x83,W
0028:  SUBWF  x81,W
002A:  BNC   003C
002C:  BNZ   0034
002E:  MOVF   x80,W
0030:  SUBWF  x82,W
0032:  BC    003C
0034:  MOVFF  07,05
0038:  MOVFF  06,04

Only one extra instruction.

Memory placement is _everything_ on bank addressed chips like this.

Best Wishes
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