10 simple tricks to optimize your C code in small embedded systems

first_img August 19, 2019 at 5:55 am September 5, 2019 at 12:43 pm Trick #4: Use if instruction without else, as possible. In this code, we assume that the condition (a == 0) happens more frequently (when using the design in the real world). Hence, we put at first : b = 0 ;  Then, we consider the alternate state (less frequent)  with a simple if instruction (without else). Trick #5: Use one dimensionnal table, instead of two dimensions. It is relatively easy to transform a 2-dimension table (with row index i and column index j) into a 1-dimension table (with index k), assuming the index will be computed as follow: k = i * N + j ; where N is the total number of columns. (all indexes are zero based) Example 6: Use instead:  Example 9: Use instead:  void main(void) { int a, b ;     switch (a)   { case 0: b = a + 5 ; break ;     case 1: b = a * 5 ; break ;     case 2: b = a – 5 ; break ;   } }void main(void) { int a, b ;     if (a == 0)  b = a + 5 ;   if (a == 1)  b = a * 5 ;   if (a == 2)  b = a – 5 ; } Log in to Reply Trick #3: Suppose we want to scan a specific set of keyboard touches (alphabetical only, case insensitive): Example 1: Use instead:  int Measure (unsigned int canal){  //more code involved here to configure the canal    //…     return ((ADRESH<<8) + ADRESL) ;}void main(void){float Vbat, Vmean=0 ; int a, cnt = 60 ;  while (cnt)   { if (TMR1IF) { Vbat = Measure(a) * 4.88 ;    Vmean += Vbat ; cnt– ; TMR1IF = 0 ; }  }  Vmean /= 60 ;}int Measure (unsigned int canal){  //more code involved here to configure the canal    //…     return ((ADRESH<<8) + ADRESL) ;}void main(void){float Vmean ; int a, cnt, Vbat, Vbat60=0 ;  while (cnt)   { if (TMR1IF) { Vbat = Measure(a) ; Vbat60 += Vbat ;    cnt– ; TMR1IF = 0 ; }  }  Vmean = (Vbat60 * 4.88) / 60 ;} Example 7: Use instead:  Continue Reading Previous Rutronik: ultra-low-power Wireless MCUs from Redpine SignalsNext HCC Embedded supports Adesto FusionHD non-volatile memories void main(void){int a, b ;  if (a – b) b = (a – 5) * 100 ;    // case 1   if (b > a) b = (a – 5) * 100 ;     // case 2   if (b – a > 0) b = (a – 5) * 100 ; // case 3 }void main(void){int a, b ;  if (a != b) b = (a – 5) * 100 ;    // case 1   if (a < b) b = (a - 5) * 100 ;      // case 2   if (a – b < 0) b = (a - 5) * 100 ; // case 3 } “As I mentioned, I used the free mode, as I didn't have the PRO edition of XC8 (too expensive). When I can't optimize code space any more, I use mixed code : C + assembly (for basline PIC, there is only 33 instructions, not so difficult to learn)” Program memory bytes used = 64 Program memory bytes used = 63 (negligible, but often, a code source contains many if/else instructions Trick #10: Re-arrange the test inside an if instruction: August 14, 2019 at 6:12 pm Program memory bytes used = 841 Program memory bytes used = 570 “Many years ago I did some tests with an MC68000 compiler to see how much faster I could make an interrupt handler than the compiler itself managed.nnI failed to equal the compiler. It used some techniques with the CPU's instruction set that I'd never s Case 1 : Program memory bytes used = 67 Case 2 : Program memory bytes used = 62 Case 3 : Program memory bytes used = 77 Case 1 : Program memory bytes used = 58 Case 2 : Program memory bytes used = 62 Case 3 : Program memory bytes used = 65 Example 4: Use instead:  Program memory bytes used = 43 Program memory bytes used = 27 “Programmers know that it is very hard to do code space optimization and speed optimization as one objective. One have to choose between. As for RTOS, PIC10/12/16F are definitively not recommended. “ void main(void) { int a, b ;     a = (b – 1) * 3 ; }void main(void) { int a, b ;     a = (b – 1) ;   a = a + a + a ; } Program memory bytes used = 79 Program memory bytes used = 74 void main(void){  for (a = 10 ; a > 0 ; a–) b = c + a ;}void main(void){  for (a = 10 ; a– ; ) b = c + a ;} void main(void){float a, b, c ;  a = (b + c) * 0.1 ;}void main(void){float a, b, c ;  a = (b + c) / 10.0 ;} Log in to Reply Example 8: Use instead:  Example 5: Use instead:  Share this:TwitterFacebookLinkedInMoreRedditTumblrPinterestWhatsAppSkypePocketTelegram Trick #2: Use multiple if instructions (without else) to replace switch instruction. Each case of the switch instruction (without default case) is replaced with an if instruction (without else). However, this trick is not relevant if the switch instruction is terminated with a default case. void main(void) { char chx ;     if (chx == ‘a’  ||  chx == ‘A’)  b = a + 5 ;   if (chx == ‘m’ ||  chx == ‘M’) b = a – 10 ;   if (chx == ‘t’   ||  chx == ‘T’)  b = a * 25 ; }void main(void) { char chx ;     // to lower case,   // caution, alphabetical only   chx = chx | 0x20 ;   if (chx == ‘a’)  b = a + 5 ;   if (chx == ‘m’) b = a – 10 ;   if (chx == ‘t’)   b = a * 25 ; } grasshopper_xl says: Program memory bytes used = 84 Program memory bytes used = 77 Example 2: Use instead:  Case 1 : Program memory bytes used = 102 Case 2 : Program memory bytes used = 160 Case 1 : Program memory bytes used = 73 Case 2 : Program memory bytes used = 114 “Even so the above made suggestions for saving code are effective, some of them may lead to increased processor load (execution time). If it’s not a real time application, then you’re ok. But when the code is used in real time applications (interrupts), it benabadji salim says: Log in to Reply Trick #8: Rework a mathematical expression containing multiplication with a constant value k, and modify it so as to use division by 1/k benabadji salim says: Example 3: Use instead:  ( This makes code run faster, as well) Log in to Reply The following simple tricks in C are dedicated for program memory space optimization . These are particularly useful for embedded systems programmers dealing with low-cost 8-bit microcontrollers with limited flash memory. While assembly language is the best choice in this case, (almost all young) hardware engineers prefer nowadays to use C langage even when the program is a relatively short control program. These 10 tips have been tested with the XC8 compiler (v1.42, free edition) to show the amount of program memory bytes involved before and after applying each code snippet on an enhanced mid-range 8-bit XLP PICmicro (a PIC16F1824). These code snippets do nothing special other than offer a proof of the concept. More clever (and sophisticated) tricks can be found here in the references listed at the end of this article.Trick #1: Use as possible, short mathematical expressions. “This is very interesting. I agree that it is always worth thinking about what you are trying to do and consider better ways to express it. However, with some of these examples, I was very surprised [disappointed] that the compiler did not manage to optimi August 19, 2019 at 10:28 am Colin Walls says: August 15, 2019 at 10:31 am eldercosta says: eldercosta says: GordonScott says: Trick #9: Prefer using unsigned values for int or long types, as possible. Be careful to keep numbers inside the interval {0, …, INT_MAX} or {0, …, LONG_MAX} “Oh, maybe the compiler is set to generate fast code instead of small code. You cannot have both, usually. So, trick #00 would be check if you are using your compile correctly.” Program memory bytes used = 570 Program memory bytes used = 559 Trick #6: When computing expressions, use integer values instead of float values, as possible. Let suppose a battery voltage which value varies between 10.5 to 14.2 volts, with step of 0.1 volt. We want to compute the mean value for each minute (for a 1s data acquisition system). Accumulate the 10-bit numerical count measure into an integer variable, without converting it (each second) to a meaningful voltage measure (float value). This conversion will be done only once, in the last step.   “The author lost me on trick #4 ou #5.nnI would start with trick #0: use a decent compiler. As Colin Walls mentioned, it is surprising the compiler is so bad at optimizing such a basic constructs. On the other hand, maybe it is a free version of it and a Log in to Reply References [1] https://ww1.microchip.com/downloads/en/AppNotes/doc8453.pdf[2] https://www.edn.com/electronics-blogs/edn-magazine–april-2013/4408338/10-C-Language-Tips-for-Hardware-Engineers[3] http://www.eventhelix.com/RealtimeMantra/Basics/OptimizingCAndCPPCode.htmSalim Mohammed Benabadji is a student at the University of Science and Technology of Oran with four years of expertise in Qt, C/C++ & QML application development in various domains. void main(void) { int a, b, c ;     if (a == 0) b = 0 ; else b = (a – c) * 100 ; }void main(void) { int a, b, c ;    b = 0 ; if (a) b = (a – c) * 100 ; } Log in to Reply void main(void){int Vbat ; // 1, 2, …, 1023   Vbat = 1023 / Vbat ;  // case 1   Vbat = (2048L * 15) / Vbat ;  // case 2 }void main(void){int Vbat ; // 1, 2, …, 1023   Vbat = 1023U / Vbat ;  // case 1   Vbat = (2048UL * 15) / Vbat ;  // case 2 } Program memory bytes used = 149 Program memory bytes used = 68 Program memory bytes used = 50 Program memory bytes used = 25 August 15, 2019 at 10:33 am void main(void) {   const char *TabMois[] =                            {“Jan”,”Feb”,”Mar”,”Apr”,”May”,”Jun”,                            “Jul”,”Aug”,”Sep”,”Oct”,”Nov”,”Dec”} ;   char ch1 = TabMois[0][0], ch2 = TabMois[0][1],           ch3 = TabMois[0][2] ; }void main(void) {   const char TabMois[] =                    “JanFebMarAprMayJunJulAugSepOctNovDec” ;   char ch1 = TabMois[0], ch2 = TabMois[1],           ch3 = TabMois[2] ; } Log in to Reply Trick #7: for instruction may be written in several ways. Look at this construction: 7 thoughts on “10 simple tricks to optimize your C code in small embedded systems” Example 10: Use instead: Leave a Reply Cancel reply You must Register or Login to post a comment. This site uses Akismet to reduce spam. Learn how your comment data is processed. August 15, 2019 at 5:37 pm last_img