View previous topic :: View next topic |
Author |
Message |
thb
Joined: 12 Jan 2006 Posts: 5 Location: Germany
|
Optimization possible? |
Posted: Mon Aug 06, 2007 6:12 pm |
|
|
Hi,
I wonder if it is possible to optimize this code. I'm not really having trouble but I think it neither looks very elegant nor very fast.
Code: |
int data=0;
int bit=0;
...
...
...
#EXT_INT
void extint_function()
{
if (input(PIN_D1)==1)
{
bit_set(data,bit);
}
else
{
bit_clear(data,bit);
}
bit++;
}
|
Some way to get rid of the "if"?
Thanks!
Thomas |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Mon Aug 06, 2007 8:04 pm |
|
|
Are you looking for the Output_bit() function? _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Aug 07, 2007 2:10 am |
|
|
The bit_clear() and bit_set() functions are not very efficient when called with a variable parameter compared to the situation where you call these functions with a constant (then just a single assembly instruction).
Here is an optimized version using a bit mask.
Code: | int8 data, bit_mask;
#INT_EXT
void extint_function()
{
if (input(PIN_D1)==1)
{
data |= bit_mask;
}
else
{
data &= bit_mask;
}
bit_mask <<= 1; // Will overflow after 8 calls. If not desired replace with rotate_left();
}
void main()
{
bit_mask=0x01;
enable_interrupts(INT_EXT);
while(1) ;
} |
An additional optimization would be to make sure data is initialized to zero before starting the data acquisition, than you can leave out the bit_clear part.
A more efficient option is to shift in the acquired data. However this gives a different behavior which I don't know if is acceptable (the bits in data are reversed and bits are moving around until you have finished 8 samples).
Code: | #INT_EXT
void extint_function()
{
shift_left(&data, sizeof(data), input(PIN_D1) );
} |
|
|
|
kevcon
Joined: 21 Feb 2007 Posts: 142 Location: Michigan, USA
|
|
Posted: Tue Aug 07, 2007 7:32 am |
|
|
You could add the line below to your code; though it only eliminates one instruction every little bit helps.
Code: |
#pragma USE FAST_IO( D )
|
Also bit is a reserved word, even though the program will compile you should avoid using reserved words as variable names. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Aug 07, 2007 8:29 am |
|
|
I don't believe there's any way to get around using the 'if()' statement. You're trying to test if a condition exists. There is, however, a way to make the if() statement a bit shorter.
Code: | .................... if(input(PIN_A0) == 1)
00A5: BSF 03.5
00A6: BSF 05.0
00A7: MOVLW 00
00A8: BCF 03.5
00A9: BTFSC 05.0
00AA: MOVLW 01
00AB: SUBLW 01
00AC: BTFSC 03.2
00AD: GOTO 0AE
.................... ;
....................
.................... if(input(PIN_A0))
00AE: BSF 03.5
00AF: BSF 05.0
00B0: BCF 03.5
00B1: BTFSS 05.0
00B2: GOTO 0B3
.................... ;
|
Notice when the '== 1' is used, the compiler inserts four extra lines. The '== 1' is not needed. To test if the input is low simply use:
It's not much but it makes things a little smaller.
Ronald |
|
|
Ttelmah Guest
|
|
Posted: Tue Aug 07, 2007 10:35 am |
|
|
Yes. It is quite worth understanding what is happening here. If you ask 'is this value 1', the compiler has to perform the actual arithmetic of subtracting '1' to see. However if you ask 'is this non zero', the compiler can simply use the value of the zero flag, set when the pin is read. Using the construct:
if(input(PIN_A0) != 0)
Gives exactly the same saving. While the other 'zero' related test:
if(input(PIN_A0) == 0)
Also gives the same advantage working the other way (as does the logic expression rnielson gives).
Hence the key is making the tests 'zero relative', rather than 'value relative'.
Best Wishes |
|
|
thb5 Guest
|
Thanks |
Posted: Tue Aug 07, 2007 6:17 pm |
|
|
Thanks for all the comments!
This gives me a good inside how to optimize.
Thomas |
|
|
|