Author Topic: How to optimize the embedded code and make efficient coding  (Read 10116 times)

0 Members and 1 Guest are viewing this topic.

Offline pyroesp

  • Regular Contributor
  • *
  • Posts: 180
  • Country: be
    • Nicolas Electronics
Re: How to optimize the embedded code and make efficient coding
« Reply #25 on: April 03, 2013, 05:42:16 pm »
@grumpydoc:
Code: [Select]
for (i = 0; i < fft_point; i++)
{
    something_fft = *(samples);
    ++samples;
    // something
    // something
}
There, fixed it. Happy now :) ?
(Just a bit tired when writing that and I swapped those lines :/)

@andersm: I "gained" an instruction in my pseudo-code example, I'm not talking about the exact compiled assembler code. That's why I said "I gained 1 instruction in this example.".

I know little about asm so I did those changes to my code, measured the time the mcu is in the transform function by setting an output high when entering the function and low when exiting the function.
The result is it's executed faster than without the changes to the code.

The program is clear enough for me to understand and it's full of comments, something everybody should do but no one does :P.
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: How to optimize the embedded code and make efficient coding
« Reply #26 on: April 03, 2013, 05:50:24 pm »
@andersm: I "gained" an instruction in my pseudo-code example, I'm not talking about the exact compiled assembler code. That's why I said "I gained 1 instruction in this example.".
Sure, but it still belongs to the class of transformations the compiler should be able to perform automatically. Unfortunately many embedded compilers are pretty bad, especially for lesser-known or single-vendor architectures.

Offline hans

  • Super Contributor
  • ***
  • Posts: 1641
  • Country: nl
Re: How to optimize the embedded code and make efficient coding
« Reply #27 on: April 03, 2013, 08:27:49 pm »
Hi
can someone suggest me how to make good code and optimize code
so that it can helps for efficient response of the system

Figure out what the key requirements are for your system.
For e.g. , if you want to respond to an incoming pulse and you need to switch off a relay quickly. Are you going to write this?

Code: [Select]
main()
{
  while(1)
  {
    ReadDataFromSlowInterface();
    UpdateDisplay();

    if (PULSE == HIGH)
    {
      RelayOff(); // quick quick quick!
    }
  }
}

You could go into straight 'micro management' and write the if {} in assembler. Is it going to help you a lot if the other 2 methods in your main loop are taking 100ms on average to complete? Not really, although the if loop may be very quick, there is other stuff in your way.

Measure things if you don't know for sure what's slow or not efficient. This can be by single stepping code, seeing the RAM usage closely in your linker map, measuring timings with scopes, etc.
If there is an issue, like I just described, see what may be interfering and what must be changed to resolve this. This can either be the interfering code or what you were testing.

For e.g. , in the last example, I could also have thought. Let's put the slow code in a timer interrupt! (OUCH):
Code: [Select]
void tmr0_interrupt()
{
  ReadDataFromSlowInterface();
  UpdateDisplay();
}

void main()
{
  setupTmr0();
  while(1)
  {
    //check it all the time.
    if (PULSE == HIGH)
    {
      RelayOff();
    }
  }
}

This is bad. If the timer fires, the CPU is stuck in the interrupt for quite some time (say 100ms). In that time, the CPU is unresponsive. Although this code has been contributing to slow responses before, making changes like this isn't going to help at all.

Instead, use something like a capture, ext interrupt, change notification pin to fire an interrupt directly when the digital pin changes. This way when a pulse comes, you can react with an interrupt..
Code: [Select]
void pulse_interrupt()
{
  if (PULSE==HIGH)
  {
    RelayOff();
  }
}
void main()
{
  setupExternalPinInterrupt();
  while(1)
  {
    ReadDataFromSlowInterface();
    UpdateDisplay();
  }
}
This way the interrupt is fired when an external pin changes (I'm assuming), and so you react instantly.

Just a small example though. In the end, I don't think writing good programs is achieved by buying big books and reading lots of tutorials. Instead, read them anyway, but do a lot of projects and programming yourself. Hands on experience counts.
Moreover if code works and is fast enough, there is no need to optimize it further. Unless you're being constrained by some value (memory or execution time constraints).. (manual) optimizations take a lot of effort.

I've actually optimized a software SPI to achieve pretty good bitrates with an ENC28J60 chip with software SPI on a dsPIC33Fj128GP804. Hardware SPI seemed to yield 3.2Mbit, where software SPI (ASM) was 3Mbit. Software SPI in C was about 1 Mbit. All I did was unroll the loop and use some bset and bclr commands...
Measurements were taken by receiving UDP packets (1.5kB each) as fast as possible.

In this case I've 'optimized' a piece of code that slowing the system down, by rewriting the routine in ASM (which is usually quicker, though, sometimes it yields almost no difference), or using a hardware module instead. Why didn't I use the hardware SPI much earlier? Because I first wrote it in ASM and I was being really lazy to set up the hardware SPI module..... (which I eventually did for the sake of seeing what was faster) :=\
« Last Edit: April 04, 2013, 05:30:17 pm by hans »
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: How to optimize the embedded code and make efficient coding
« Reply #28 on: April 03, 2013, 08:51:47 pm »
Although there are all sorts of clever things a good (expensive) compiler can potentially do, in practice many don't, ...
Let's flip that around and say that immature compilers often generate naive code. And if you're seriously trying to squeeze performance out of a system based on a crap-tastic compiler, one of your first steps ought to be finding a better compiler (assuming that's an option).

It seems that many of the OEM offerings for 8- and 16-bit mcus fall into the crap-tastic category. That's one of the reasons I like reaching for 32-bit ARM chips because GCC is very mature and costs $0.
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: How to optimize the embedded code and make efficient coding
« Reply #29 on: April 03, 2013, 08:57:33 pm »
Quote
There, fixed it. Happy now :) ?
(Just a bit tired when writing that and I swapped those lines :/)
There is no need and I do not wish you to "make me happy".

Actually swapping those lines around was useful for discussion (I suspected you had meant it the other way).

I do want to try to illustrate that you might be surprised at which C code yields the "best" assembler and that this is a fragile concept depending on several variables (platform, C compiler, optimisation switches....). It is thus best avoided in production code.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26907
  • Country: nl
    • NCT Developments
Re: How to optimize the embedded code and make efficient coding
« Reply #30 on: April 03, 2013, 11:06:32 pm »
At some point you may need to get the most of a compiler for a particular platform. In that case your still better off shuffling C code around an do manual loop unrolling than programming the algorithm in assembler.

However, the best way to optimise is to start with a smart algorithm which doesn't need a lot of processing to start with.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf