optimization ideas?

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

I have part of an ISR timer section on an Xmega to do a simple slow blink...What I created works 100% completely fine.  However, I somewhat don't like the fact that the port is always written every isr cycle (whether needed or not, seems wasteful).   If I put in more conditionals or logic, I might avoid that, but then the extra logic seems to take as just as much time.  None of the values are fixed (other than "4"), since the freq & width are changed (elsewhere) depending on various modes.  The actual timing values are not extremely critical (such as being off a few counts). Any thoughts?

 

  ...isr stuff...
  ...more isr stuff...
green_time++;
if (green_width<green_time)
  PORTE_Virt.OUT &= ~GRN_LED_PE;   //LED turned OFF
 else
  PORTE_Virt.OUT |= GRN_LED_PE;     //LED turned ON
  
if (green_time>green_period) green_time=0;  //Period is used up

 

 

 

 

 

 

 

 

 

 

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sat. Jul 2, 2016 - 04:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you feel bad for the poor overworked PORTE? If so, don't worry about it, it'll get by. There's not much room for optimization there and there's even less need if it's working fine as is. Even so, the best way to optimize what you have would be to fire the ISR only when an update is needed, but if you're doing other things in the same ISR that's not an option.

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

"Do you feel bad for the poor overworked PORTE? If so, don't worry about it"

 No, but was wondering if there was an obvious way I was overlooking (I suppose using a PWM output would be one, except no good for the overall need, multiple leds, freqs, etc)

 

 

also is there another way to do this type of construct (green_period is NOT a power of 2, ex:5773):  

if (green_time>green_period) green_time=0;  //Period is used up

"and there's even less need if it's working fine as is"

 ...True, just wondering if I'm overlooking the secret opcode set

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sat. Jul 2, 2016 - 04:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The Xmega has got fast steering registers like OUTSET.
It also has VPORTs.
This makes the Xmega far faster than a Mega.
.
Regarding wastefulness. Sort out your logic. If you only want to write to the LED when there is a change, use XOR to decide.

Only you know what you want your program to do.
.

David.

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

Good points...

 

"Only you know what you want your program to do"

    ...tell that to the customer  :)

 

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Fri. Jul 1, 2016 - 11:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

can you show the ASM code?

normally it's faster to check for 0 , preload with periode use -- and check against 0 .

 

I don't know your structure, but perhaps you can avoid that you variables are volatile (but static to the ISR), perhaps it could save some loads.

If they have to be volatile then make a copy (at first use) in the ISR, (that don't work if you use different levels of ISR. that use those.)

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

Don't change it.

A new improved version would not be as obviously correct.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

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

I use the RTC interrupt to blink my LED.  That's what it is there for, isn't it?  laugh

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

Sometimes, you just have to accept the extra action because the "cost" is lower. This is an excellent example of that. Testing for whether or not something is already CLEARED and only CLEAR if it is SET is a common case. Testing will cost more than doing it every time. It is a very common coding "issue" and I write "issue" because (mostly) it is only a psychological issue, not a physical one. The real criterion is whether or not the test to execute or not is more or less costly than doing it every time. 

 

Here is an example of when it might be more costly to do it every time. Suppose that you have an I2C peripheral with some control variable in a register. Changing that variable is relatively costly because of the I2C transaction involved. So, one way to deal with this is to keep a local copy of that control variable, and test whether or not it needs to be changed. This one can sneak up on you because there is often a function such as I2CWrite(RegisterAddr,RegisterValue) that hides the cost from you. Then, it is easy for you, the programmer, to forget what the cost is and blindly put in function calls. 

 

But, in the OP's case, it is the other way around. The cost saving of not testing outweighs the cost of testing. 

 

A big question is "What do you mean by cost?" One cost could certainly be code size. For the OP's case, this cost is pretty clear. But, the case of the I2C device is less clear on this, because you "only" add a function call. Another aspect of cost is execution time. This could be a very important consideration in the I2C example. Another factor, often overlooked, is invariance of execution time through a particular branch of the program. If you have to test, then some passes will take more time than others; this cost usually is a "don't care", but sometimes it is important. Stack or SRAM usage might be another cost factor. There is no one unique expression for cost; what might be costly in one place could be little or no cost (or cost not mattering) in another. 

 

In the end, you have to use your brain, and evaluate the situation carefully. The rub: to evaluate carefully, you must have knowledge of the facts. That may mean lots of reading or experimenting.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Sat. Jul 2, 2016 - 05:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well it is three volatile loads and one or two stores, which may require storing more registers on the stack.

Below would take more flash and ram but might give a speed improvement.

How about

  ...more isr stuff...
if (--green_time==0) {              //on timer trigger
    if (greenison) {                    //toggle LED state
       greenison=0;
       PORTE_Virt.OUT &= ~GRN_LED_PE;       //turn LED off
       green_time=green_period-green_width; //off time
   } else {
       greenison=1;
       PORTE_Virt.OUT |= GRN_LED_PE;        //turn LED om
       green_time=green_width;              //on time
    }
}

 

 

Last Edited: Sat. Jul 2, 2016 - 11:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not sure what device this is, but using (pseudo-code, as I don't know the PORTE_Virt.OUT format):

if (--green_time==0) {              //on timer trigger
    if (!!(GRN_LED_PORT & GRN_LED_PIN_MASK)) {   // If green LED on
       PORTE_Virt.OUT &= ~GRN_LED_PE;       //turn LED off
       green_time=green_period-green_width; //off time
   } else {
       PORTE_Virt.OUT |= GRN_LED_PE;        //turn LED om
       green_time=green_width;              //on time
    }
}

The "if" test of LED on should compile to a sbis without adding a variable (although the compiler may do that with the previous code).

 

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
time_left--;
if(0==time_left) {
    if(LED is ON) { LED_OFF(); time_left=off_time; }
    else          { LED_ON();  time_left=on_time;  }
}

 

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

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

It's not always nice C make nice ASM code.

 

I guess that all variables are 8 bit, if not make something like a div256++ (static in ISR) and only run the LED code if it's ==0

 

I don't have a xmega here but the ASM structure will be something like this: (untested)

    lds r24,green
    dec r24
    brne L1
    lds r24,periode
    sbi LED
    rjmp L2
L1: lds r25,width
    cp r25,r24
    brne L2
    cbi LED
L2: sts green,r24   

if you want to save code the rjmp isn't needed.

this will have a worst case of 13 clk on a normal AVR  , but I guess that some of the instructions is a tad faster on xmega. 

If it needs to be faster place in reg. 

 

How close the different C implementations are I don't know, but the normal problem is that worst case often much longer than normal, and if too many of those will break the flow.

 

changed typo

Last Edited: Tue. Jul 5, 2016 - 05:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Jim:

 

Yeah, there can be severe efficiency degradation for more complex situations.  For example, some loop that keep's updating the LCD with whatever is in the messaging string.  Rewriting every cycle can create a flickering display, rather than only doing it once per message update (only as needed when a different message comes up). Of course in this case, the checking or state machine code is probably a timesaver compared to a constant LCD rewrite.

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

I was asking a similar question that the OP is asking in this thread:

 

https://www.avrfreaks.net/forum/a...

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user