Programming OCD's and effiecient coding

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I used to be an assembler programmer until I saw the light and 'learned' (i'm still learning) to program C, I stopped getting the headaches but there is still something inside me that looks at the code produced and wants to produce something that is efficient as possible... probably verging on OCD or actually is considering the problem.

Today I wrote and compiled this statement

loadCurrent = (((int16_t)loadCurrent - LOAD_STEP) > 0) ? loadCurrent - LOAD_STEP : 0;

loadCurrent and LOAD_STEP are uint8_t variables stored in RAM and loadCurrent was accessed by the preceeding statements and placed in R24.

The code produced becomes

				loadCurrent = (((int16_t)loadCurrent - LOAD_STEP) > 0) ? loadCurrent - LOAD_STEP : 0;
    4b9e:	28 2f       	mov	r18, r24
    4ba0:	30 e0       	ldi	r19, 0x00	; 0
    4ba2:	80 91 e6 09 	lds	r24, 0x09E6
    4ba6:	28 1b       	sub	r18, r24
    4ba8:	31 09       	sbc	r19, r1
    4baa:	37 ff       	sbrs	r19, 7
    4bac:	02 c0       	rjmp	.+4      	; 0x4bb2 
    4bae:	20 e0       	ldi	r18, 0x00	; 0
    4bb0:	30 e0       	ldi	r19, 0x00	; 0
    4bb2:	20 93 64 04 	sts	0x0464, r18

The code produced is not unreasonable but I would have written:

	mov   r18, r24      ;stick loadCurrent in to temp
	lds   r24, 0x09E6   ;get LOAD_STEP
	sub   r18, r24      ;temp -= LOAD_STEP
	brnc  NOT_MINUS     ;check if rolled over
	ldi   r18, 0x00     ;if so temp = 0
NOT_MINUS:
	sts   0x0464, r18   ;save load current

Is there a way to write this expression to regain my lost processing time or should I just forget about it and accept it as a trade off for the lack of dull aches in my head? Also as a result of promoting loadCurrent to an int16 R19 is cleared at the end for no effect.

Thanks

John.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But your desired code relies on them being 8 bit yet in the C you deliberately cast to 16 bits - why? What's worse it's a cast to signed 16 bits which generally always involves more overhead than unsigned.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

True, hence my post. My reasoning for the int16 cast was to detect a minus number.
I'm looking for suggestions to improve my coding and more effiecient compiled code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#define LOAD_STEP 78
uint8_t loadCurrent;
...
void bum(void)
{
   if (loadCurrent > LOAD_STEP) loadCurrent -= LOAD_STEP;
   else loadCurrent = 0;
}

produces:

bum:
	lds r24,loadCurrent
	cpi r24,lo8(79)
	brlo .L2
	subi r24,lo8(-(-78))
	sts loadCurrent,r24
	ret
.L2:
	sts loadCurrent,__zero_reg__
	ret

IMHO this is more readable, takes account of an unsigned comparison. Yes, I could write it more efficiently in ASM. But who cares? Are you going to save the world with the missing microseconds?

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Superb suggestion! Gold star.

Putting back in to my orignal statements produces:

				loadCurrent = (loadCurrent > LOAD_STEP) ? loadCurrent - LOAD_STEP : 0;
    4b9c:	90 91 e6 09 	lds	r25, 0x09E6
    4ba0:	98 17       	cp	r25, r24
    4ba2:	10 f0       	brcs	.+4      	; 0x4ba8 
    4ba4:	80 e0       	ldi	r24, 0x00	; 0
    4ba6:	01 c0       	rjmp	.+2      	; 0x4baa 
    4ba8:	89 1b       	sub	r24, r25
    4baa:	80 93 64 04 	sts	0x0464, r24

or

				if(loadCurrent > LOAD_STEP) loadCurrent -= LOAD_STEP;
    4b9e:	90 91 e6 09 	lds	r25, 0x09E6
    4ba2:	98 17       	cp	r25, r24
    4ba4:	20 f4       	brcc	.+8      	; 0x4bae 
    4ba6:	89 1b       	sub	r24, r25
    4ba8:	80 93 64 04 	sts	0x0464, r24
    4bac:	02 c0       	rjmp	.+4      	; 0x4bb2 
				else loadCurrent = 0;
    4bae:	10 92 64 04 	sts	0x0464, r1

or

				loadCurrent = (loadCurrent < LOAD_STEP) ? 0 : loadCurrent - LOAD_STEP;

    4b9c:	90 91 e6 09 	lds	r25, 0x09E6
    4ba0:	89 17       	cp	r24, r25
    4ba2:	10 f4       	brcc	.+4      	; 0x4ba8 
    4ba4:	80 e0       	ldi	r24, 0x00	; 0
    4ba6:	01 c0       	rjmp	.+2      	; 0x4baa 
    4ba8:	89 1b       	sub	r24, r25
    4baa:	80 93 64 04 	sts	0x0464, r24

Loosing only one instruction, 70ns worse off but I'll live with it.

Cheers!

John.