GNU-GCC Compiler Optimisation for the evaluation of the ++Var/Var++/V--

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

Dear all, as we all are much of a familiar with the expressions involving those shortcuts >> ++Var<< which means  "variable=variable+variable" or >> --Var which does the opposite by subtracting --var="variable-variable".

 

if(brightness==0)
      {
        direction=1;
      }
      if(brightness==255)
      {
        direction==-1;
      }
      brightness+=direction; << this equation 

if the "direction =-1", then the above mentioned statement will be  "brightness=brightness+(-1)" so considering math. and if we solve this having in mind tthe math. then we need to subtract from brightness "-1" so it we be "brightness= brigthness-1". Is this correct thinking of C language and the way it interprets this kind of math.? and in which way the GNU-GCC compiler is taking care of this stuff? (^:^)

work in progress...

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

What type and size are your variables?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

Why should any of this be a mystery when the .lss or the .s file after -save-temps are available for you to study?

EDIT: so I built this:

uint8_t brightness, direction;

int main(void)
{
    /* Replace with your application code */
    while (1) 
    {
		brightness = PINB;
		if (brightness == 0)
		{
			direction = 1;
		}
		if (brightness == 255)
		{
			direction = -1;
		}
		brightness += direction;
    }
}

(I deliberately used PINB in there because otherwise the optimiser is too smart and thinks it already knows the value of brightness!). I get:

  7c:	21 e0       	ldi	r18, 0x01	; 1
  7e:	86 b3       	in	r24, 0x16	; 22
  80:	81 11       	cpse	r24, r1
  82:	03 c0       	rjmp	.+6      	; 0x8a <main+0xe>
  84:	20 93 60 00 	sts	0x0060, r18	; 0x800060 <_edata>
  88:	04 c0       	rjmp	.+8      	; 0x92 <main+0x16>
  8a:	8f 3f       	cpi	r24, 0xFF	; 255
  8c:	11 f4       	brne	.+4      	; 0x92 <main+0x16>
  8e:	80 93 60 00 	sts	0x0060, r24	; 0x800060 <_edata>
  92:	90 91 60 00 	lds	r25, 0x0060	; 0x800060 <_edata>
  96:	89 0f       	add	r24, r25
  98:	80 93 61 00 	sts	0x0061, r24	; 0x800061 <brightness>

I'm a bit disappointed about the lack of source annotation in that - I think some goon at Atmel thinks that because I said "Release" I shouldn't get -g either!!

Last Edited: Fri. Sep 28, 2018 - 02:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What type and size are your variables? 

    ops... 

      - uint8t_t brightness,

      - int8t_t  direction, this one is with signed 0-255 and then back.

work in progress...

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

Correcting those types and adding the -g3 option the generated code is:

		brightness = PINB;
  7e:	86 b3       	in	r24, 0x16	; 22
		if (brightness == 0)
  80:	81 11       	cpse	r24, r1
  82:	03 c0       	rjmp	.+6      	; 0x8a <main+0xe>
		{
			direction = 1;
  84:	20 93 60 00 	sts	0x0060, r18	; 0x800060 <_edata>
  88:	04 c0       	rjmp	.+8      	; 0x92 <main+0x16>
		}
		if (brightness == 255)
  8a:	8f 3f       	cpi	r24, 0xFF	; 255
  8c:	11 f4       	brne	.+4      	; 0x92 <main+0x16>
		{
			direction = -1;
  8e:	80 93 60 00 	sts	0x0060, r24	; 0x800060 <_edata>
		}
		brightness += direction;
  92:	90 91 60 00 	lds	r25, 0x0060	; 0x800060 <_edata>
  96:	89 0f       	add	r24, r25
  98:	80 93 61 00 	sts	0x0061, r24	; 0x800061 <brightness>

It's probably a bit fierce making "direction" global as this forces the "sts" in there so bringing it local achieves:

		brightness = PINB;
  7c:	86 b3       	in	r24, 0x16	; 22
		if (brightness == 0)
  7e:	88 23       	and	r24, r24
  80:	21 f0       	breq	.+8      	; 0x8a <main+0xe>
		{
			direction = 1;
		}
		if (brightness == 255)
  82:	8f 3f       	cpi	r24, 0xFF	; 255
  84:	19 f4       	brne	.+6      	; 0x8c <main+0x10>
		{
			direction = -1;
  86:	9f ef       	ldi	r25, 0xFF	; 255
  88:	01 c0       	rjmp	.+2      	; 0x8c <main+0x10>
    while (1) 
    {
		brightness = PINB;
		if (brightness == 0)
		{
			direction = 1;
  8a:	91 e0       	ldi	r25, 0x01	; 1
		}
		if (brightness == 255)
		{
			direction = -1;
		}
		brightness += direction;
  8c:	89 0f       	add	r24, r25
  8e:	80 93 60 00 	sts	0x0060, r24	; 0x800060 <_edata>

 

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

++Var means: Increment Var before it is used somewhere else, and not  "variable=variable+variable"

Your post is full of other errors which I won't point out.
Read some C manual carefully.

The error in your code example is in the line:

        direction==-1;

This is not an assignment, but it is a comparison.

"direction" is compared to "-1" and the result of the comparison is thrown away.

You probably meant to write:

        direction = -1;

A tip for future development:

Insert spaces around those arithmatic symbols so they stand out more.

It makes it easier to spot simple errors like above.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

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

Dave_Zeb. wrote:
- int8t_t direction, this one is with signed 0-255 and then back.

Ah No, -128 to +127

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

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

Now something strange happened.

I saw a post without any followups.

I wrote a reply and clicked on [Post].

Then ki0bk's reply turned up below my own reply.

Scrolling back I saw 4 other replies, but apparently everybody looked over the difference between the assignment and comparison.

Yet another reason to add those spaces!

But where did those 20 minutes go?

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

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

Paulvdh wrote:
but apparently everybody looked over the difference between the assignment and comparison.
Err no....

		if (brightness == 255)
		{
			direction = -1;
		}

I already silently fixed the error in #3.

 

I noticed it because I tidied up the OPs code by adding spaces on each side of each C operator (as I always do) at which point his typo was blindingly obvious. I didn't mention it because it's not pertinent to what he was asking and was clearly a typo when he posted the pseudo code in #1

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

@clawson. I noticed you silenty corrected the error during tidying up.

But I still do think it is the cause of the error in his code.

"direction" never gets set to -1 which leads to direction never getting decremented.

 

I guess it has something to do with the level that people operate at, and the level at which they make mistakes.

 

My eyes hurt when I read:

Dave_Zeb. wrote:
then we need to subtract from brightness "-1" so it we be "brightness= brigthness-1".

OP is clearly a beginner with C and (still) has some trouble in keeping all those operators apart.

Dave_Zeb. wrote:
Location: Berlin
  (Probably) not being a native English speaker might also have something to do with it.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

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

 the cause of the error in his code.

But OP is not reporting a fault in his code?? He's simply asking for the most efficient way to implement a zig-zag counter. With corrections, the generated asm I showed, seems to suggest that what he proposes is a fairly well optimized way to approach this. My input here was simply to point out to OP that this is the kind of investigation/experiment you can easily do yourself - work out a test case - build it - study the LSS.

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

thanks clawson for nice example. And yes actually it was my typo and the original code looks like this: I made this post in a rush so i did not check it at the end, which is my fault.  I go do my homework now which is studying English and the C programming.

int main(void) {
uint8_t brightness = 0;
int8_t direction = 1;
LED_DDR = 0xff;
while (1) {
if (brightness == 0) {
direction = 1;
}
if (brightness == 255) {
direction = -1;
}
brightness += direction;
pwm(brightness);
}
return (0); 
}

 

work in progress...

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

And yes actually it was my typo

Please please please don't type in code.  Use copy/paste.  Nobody likes chasing down blind alleys.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Notice how the compiler reused the unsigned comparison constant 255 as signed value -1 for direction (that is, the value in r24). This is a nicely done optimization.

 

		if (brightness == 255)
  8a:	8f 3f       	cpi	r24, 0xFF	; 255
  8c:	11 f4       	brne	.+4      	; 0x92 <main+0x16>
		{
			direction = -1;
  8e:	80 93 60 00 	sts	0x0060, r24	; 0x800060 <_edata>