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

four lines of code - 152++ instruct cycles of ouch ?

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



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

View user's profile Send private message AIM Address

four lines of code - 152++ instruct cycles of ouch ?
PostPosted: Mon Aug 03, 2009 7:47 pm     Reply with quote

oh - would anybody care to thrash me ?

i have these four lines of code ( for an f887 v4.085 )
that generate 152 instructions and sucks up even more clock cycles to execute

fadd is an unsigned int8 used as an offset into EEPROM space,
and myid and myidck are both unsigned int16's

IS THERE A BETTER WAY TO DO THIS - instruction count wise ?
i do several similar uses of EEPROM and the code space burden is the worst thing in the program


Code:

   write_eeprom( fadd++, make8( MyId, 0)); 
   write_eeprom( fadd++, make8( MyId, 1)); 
   write_eeprom( fadd++, make8( MyIdCk, 0));
   write_eeprom( fadd, make8( MyIdCk, 1));
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 03, 2009 9:07 pm     Reply with quote

http://www.ccsinfo.com/forum/viewtopic.php?t=23844
asmboy



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

View user's profile Send private message AIM Address

which cuts it down some ....
PostPosted: Mon Aug 03, 2009 9:25 pm     Reply with quote

after profiling the change that gets down to 115 instrux total
and is very worthwhile since the program is crafted to never have an issue with exec time , when EEPROM is being written to -
that gets it down 25% - which is better than before

i keep wondering if there is a more efficient way to access the bytes of the long ints as well - better than make8 - but looking at the ASM code for THAT does not give me much hope
n-squared



Joined: 03 Oct 2006
Posts: 99

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Aug 04, 2009 1:03 am     Reply with quote

asmboy,
Since CCS C duplicates code freely, it is sometimes better to create a one-line function and call it repeatedly.

Code:

void  store_to_eeprom(int8 fadd, int8 dat)
  {
  write_eeprom(fadd, dat);
  }

void main()
  {
  int8 fadd;
  int16 dat, dat2;
  fadd = 2;
  store_to_eeprom(fadd++, make8(dat, 0));
  store_to_eeprom(fadd++, make8(dat, 1));
  store_to_eeprom(fadd++, make8(dat2, 0));
  store_to_eeprom(fadd, make8(dat2, 1));
}


I counted 57 instructions in the four lines plus function for the F887.

Regards
Noam
_________________
Every solution has a problem.
asmboy



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

View user's profile Send private message AIM Address

what number base is that ???
PostPosted: Tue Aug 04, 2009 8:35 am     Reply with quote

So here is a link to what compiled for me - the LST file.

After making assignment changes and merging it with a live bit of code
see for yourself at

http://64.128.110.53/eep.txt

Am I and n-sq using different number bases when we count ?

I get way over a hundred instructs in the LST - but especially
the block of 28 instrux - the "wrapper" - that is executed 4 times
in runtime.

How am I misreading to LST file to get such a large number of
1- code space instructs
2- wicked big number of executed instructs ?

WAY more that N-sq counted or saw.
n-squared



Joined: 03 Oct 2006
Posts: 99

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Aug 04, 2009 9:09 am     Reply with quote

Asmboy,
I included the complete listing below, for your review.
It seems to me that in your program the variables are located in different banks, which causes the compiler to switch back and forth between them.

Best regards
Noam

Code:

CCS PCM C Compiler, Version 4.091, 43746               04-àåâåñè-09 22:45

               Filename: C:\DEVELOP\test\main.lst

               ROM used: 108 words (1%)
                         Largest free fragment is 2048
               RAM used: 13 (4%) at main() level
                         15 (4%) worst case
               Stack:    1 locations

*
0000:  NOP
0001:  MOVLW  00
0002:  MOVWF  0A
0003:  GOTO   022
.................... #include <16F887.h>
.................... //////// Standard Header file for the PIC16F887 device ////////////////
.................... #device PIC16F887
.................... #list
.................... 
.................... #device ICD=TRUE
.................... #device adc=8
.................... 
.................... #FUSES NOWDT                   //No Watch Dog Timer
.................... #FUSES INTRC_IO                //Internal RC Osc, no CLKOUT
.................... #FUSES NOPROTECT               //Code not protected from reading
.................... #FUSES NOBROWNOUT              //No brownout reset
.................... #FUSES NOPUT                   //No Power Up Timer
.................... #FUSES NOCPD                   //No EE protection
.................... #FUSES NODEBUG                 //No Debug mode for ICD
.................... #FUSES NOLVP                   //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
.................... #FUSES NOWRT                   //Program memory not write protected
.................... #FUSES IESO                    //Internal External Switch Over mode enabled
.................... #FUSES FCMEN                   //Fail-safe clock monitor enabled
.................... #FUSES MCLR                    //Master Clear pin enabled
.................... #use delay(clock=8000000,RESTART_WDT)
.................... #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
.................... 
.................... void  store_to_eeprom(int8 fadd, int8 dat)
....................   {
....................   write_eeprom(fadd, dat);
0004:  MOVF   28,W
0005:  BSF    03.6
0006:  MOVWF  0D
0007:  BCF    03.6
0008:  MOVF   29,W
0009:  BSF    03.6
000A:  MOVWF  0C
000B:  BSF    03.5
000C:  BCF    0C.7
000D:  BSF    0C.2
000E:  BCF    03.5
000F:  BCF    03.6
0010:  MOVF   0B,W
0011:  MOVWF  77
0012:  BCF    0B.7
0013:  BSF    03.5
0014:  BSF    03.6
0015:  MOVLW  55
0016:  MOVWF  0D
0017:  MOVLW  AA
0018:  MOVWF  0D
0019:  BSF    0C.1
001A:  BTFSC  0C.1
001B:  GOTO   01A
001C:  BCF    0C.2
001D:  MOVF   77,W
001E:  BCF    03.5
001F:  BCF    03.6
0020:  IORWF  0B,F
....................   }
0021:  RETLW  00
.................... 
.................... void main()
.................... {
0022:  CLRF   04
0023:  BCF    03.7
0024:  MOVLW  1F
0025:  ANDWF  03,F
0026:  MOVLW  71
0027:  BSF    03.5
0028:  MOVWF  0F
0029:  MOVF   0F,W
002A:  BSF    03.6
002B:  BCF    07.3
002C:  MOVLW  0C
002D:  BCF    03.6
002E:  MOVWF  19
002F:  MOVLW  A2
0030:  MOVWF  18
0031:  MOVLW  90
0032:  BCF    03.5
0033:  MOVWF  18
0034:  BSF    03.5
0035:  BSF    03.6
0036:  MOVF   09,W
0037:  ANDLW  C0
0038:  MOVWF  09
0039:  BCF    03.6
003A:  BCF    1F.4
003B:  BCF    1F.5
003C:  MOVLW  00
003D:  BSF    03.6
003E:  MOVWF  08
003F:  BCF    03.5
0040:  CLRF   07
0041:  CLRF   08
0042:  CLRF   09
.................... 
.................... int8 fadd;
.................... int16 dat, dat2;
.................... 
....................   fadd = 2;
0043:  MOVLW  02
0044:  BCF    03.6
0045:  MOVWF  21
....................   store_to_eeprom(fadd++, make8(dat, 0));
0046:  MOVF   21,W
0047:  INCF   21,F
0048:  MOVWF  26
0049:  MOVF   22,W
004A:  MOVWF  27
004B:  MOVF   26,W
004C:  MOVWF  28
004D:  MOVF   22,W
004E:  MOVWF  29
004F:  CALL   004
....................   store_to_eeprom(fadd++, make8(dat, 1));
0050:  MOVF   21,W
0051:  INCF   21,F
0052:  MOVWF  26
0053:  MOVF   23,W
0054:  MOVWF  27
0055:  MOVF   26,W
0056:  MOVWF  28
0057:  MOVF   23,W
0058:  MOVWF  29
0059:  CALL   004
....................   store_to_eeprom(fadd++, make8(dat2, 0));
005A:  MOVF   21,W
005B:  INCF   21,F
005C:  MOVWF  26
005D:  MOVF   24,W
005E:  MOVWF  27
005F:  MOVF   26,W
0060:  MOVWF  28
0061:  MOVF   24,W
0062:  MOVWF  29
0063:  CALL   004
....................   store_to_eeprom(fadd, make8(dat2, 1));
0064:  MOVF   25,W
0065:  MOVWF  26
0066:  MOVF   21,W
0067:  MOVWF  28
0068:  MOVF   25,W
0069:  MOVWF  29
006A:  CALL   004
.................... }
006B:  GOTO   06B

Configuration Fuses:
   Word  1: 0CF4   INTRC_IO NOWDT NOPUT MCLR NOPROTECT NOCPD NOBROWNOUT IESO FCMEN NOLVP DEBUG
   Word  2: 3FFF   NOWRT BORV40

_________________
Every solution has a problem.
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Tue Aug 04, 2009 12:43 pm     Reply with quote

Bank switching happens when you have non trivial programs
that use a lot of variables and buffers.

I need enough large char buffers in the code this was appended to ( 87% Ram used - 91% code space F887) - that many small vars get stuck in whatever space the compiler can stash them.

I should have noticed the bank switch overhead.
n-squared



Joined: 03 Oct 2006
Posts: 99

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Aug 04, 2009 5:36 pm     Reply with quote

asmb,

You're welcome.

Sometimes we make TWO misteaks at a thyme.

N-sq
_________________
Every solution has a problem.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Aug 04, 2009 6:53 pm     Reply with quote

As a general optimization trick in the PIC16, try to keep the memory hungry variables out of the first bank. This will create the most effective use of the access bank feature in the instruction set.
The CCS compiler assigns memory locations to the variables in the order they appear in the source code. Check the symbol file (*.sym) to see which large buffers are located in low memory and try to move these to other memory banks.

Furthermore the compiler is doing a poor job:
Code:
....................   store_to_eeprom(fadd++, make8(dat1, 1));
0050:  MOVF   fadd,W
0051:  INCF   fadd,F
0052:  MOVWF  @@27
0053:  MOVF   dat1+1,W
0054:  MOVWF  @@28
0055:  MOVF   @@27,W
0056:  MOVWF  fadd_l
0057:  MOVF   dat1+1,W
0058:  MOVWF  dat_l
0059:  CALL   store_to_eeprom
This is not the most efficient generated code. The make8 is treated like a function and the return value is stored in a temporary location. Replacing the make8 function by a union saves three instructions:
Code:
union
{
  int16 dat;
  char c[2];
} foo;

....................   store_to_eeprom(fadd++, foo.c[1]);
005A:  MOVF   fadd,W
005B:  INCF   fadd,F
005C:  MOVWF  @@27
005D:  MOVWF  fadd_l
005E:  MOVF   foo+1,W
005F:  MOVWF  dat_l
0060:  CALL   store_to_eeprom
This can be coded more nicely by creating a typedef for the union.

Another instruction can be saved by moving the increment out of the function call:
Code:
union
{
  int16 dat;
  char c[2];
} foo;

....................   store_to_eeprom(fadd,   foo.c[1]);
0061:  MOVF   fadd,W
0062:  MOVWF  fadd_l
0063:  MOVF   foo+1,W
0064:  MOVWF  dat_l
0065:  CALL   store_to_eeprom
....................   fadd++;
0066:  INCF   fadd,F
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Tue Aug 04, 2009 7:54 pm     Reply with quote

DUH I shoulda thought of that.
THANK you ckielstra - that is a BIG help for more than just this one instance.

Brilliant and I can use the same sort of thing in several other places where I am messing with make8() and make16 from a int32
for no better reason than it was EZ and the compiler manual pages && doc kinda pointed in that direction.

I OWE U 1
n-squared



Joined: 03 Oct 2006
Posts: 99

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Aug 04, 2009 9:40 pm     Reply with quote

ckielstra,
Thanks for the tips.
I didn't get this far in optimizing the code.

Best regards
Noam
_________________
Every solution has a problem.
n-squared



Joined: 03 Oct 2006
Posts: 99

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Aug 04, 2009 9:59 pm     Reply with quote

As a further exercise, if we make the fadd variable a global and let the store_to_eeprom() increment it after each write, we save further.
For each sequence of writes, we set fadd to the first address and then start calling the function:

Code:

#include <16F887.h>
#device ICD=TRUE
#device adc=8

#FUSES NOWDT                   //No Watch Dog Timer
#FUSES INTRC_IO                //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT               //Code not protected from reading
#FUSES NOBROWNOUT              //No brownout reset
#FUSES NOPUT                   //No Power Up Timer
#FUSES NOCPD                   //No EE protection
#FUSES NODEBUG                 //No Debug mode for ICD
#FUSES NOLVP                   //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                   //Program memory not write protected
#FUSES IESO                    //Internal External Switch Over mode enabled
#FUSES FCMEN                   //Fail-safe clock monitor enabled
#FUSES MCLR                    //Master Clear pin enabled
#use delay(clock=8000000,RESTART_WDT)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

typedef union {
    int16 dat;
    int8  byt[2];
} WBX;

int8 fadd;

void  store_to_eeprom(int8 dat)
  {
  write_eeprom(fadd, dat);
  fadd++;
  }

void main()
  {
  WBX d1,d2;
  fadd = 2; // initialize eeprom address
  store_to_eeprom(d1.byt[0]);
  store_to_eeprom(d1.byt[1]);
  store_to_eeprom(d2.byt[0]);
  store_to_eeprom(d2.byt[1]);
  }


This gets it down to 42 instructions.
_________________
Every solution has a problem.
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