Teach you how to optimize the C language program

Source: Internet
Author: User
Tags arrays constant pow
Program to optimize, usually refers to the optimizer code or program execution speed. Optimizing the code and optimizing the speed is actually a shield of unity, generally optimize the size of the code, will bring about the increase in execution time, if the program is optimized to execute speed, usually bring the side effects of code increase, it is difficult to have both the fish and bear paws, only in the design of a balance point

I. Optimization of the program structure

1, the writing structure of the program
Although the writing format does not affect the generated code quality, but in the actual writing program should be respected to follow certain rules of writing, a clear and clear writing procedures, conducive to future maintenance. When writing a program, especially when statements such as while, for, Do...while, If...elst, switch...case, or nested combinations of these statements, you should use the writing form of "indented".

2, identifiers
The user identifier used in the program, except to follow the naming rules for identifiers, generally do not use algebraic symbols (such as a, B, X1, y1) as variable names, you should select the relevant meaning of English words (or abbreviations) or Hanyu Pinyin as identifiers, to increase the readability of the program, such as: count, Number1, Red, work and so on.

3. Program Structure
C language is a high-level programming language, provides a very complete standardized process control structure. Therefore, in the use of C language Design SCM Application System program, we should first pay attention to the use of structured program design method, so that the entire application System program structure is clear, easy to debug and maintenance. In a larger application, the entire program is usually divided into several modules, different modules to complete different functions. Each module can be written separately, and even can be written by different programmers, the general single module to complete the function is simpler, design and debugging is relatively easy. In the C language, a function can be considered a module. The so-called program modularity, not only to the entire program into a number of functional modules, more importantly, we should also pay attention to maintain the relative independence of the variables between the modules, that is, to maintain the independence of the module, as far as possible use of global variables. For some common functional modules, it can also be encapsulated as an application library so that it can be invoked directly when needed. However, when using modularity, partitioning a module too thin and too small can lead to inefficient execution of programs (protecting and restoring registers takes some time to enter and exit a function).

4. Defining constants
In the programmed design process, for the constant use of some constants, if it is written directly to the program, once the constant value of the change, you must find out the program all the constants, and one by one to modify, which will inevitably reduce the maintainability of the program. Therefore, as far as possible, the preprocessing command should be used to define constants, and the input errors can also be avoided.

5. Reduce Judgment Statement
where conditional compilation (IFDEF) is used, conditional compilation is used instead of the IF statement, which helps reduce the length of the compiled code and makes it less useful to use judgments without judgment statements.

6. Expression type
Where the precedence order of the various operations in an expression is not clear or confusing, the parentheses should explicitly specify their order of precedence. An expression can not be written too complex, if the expression is too complex, after a long time, they are not easy to read, not conducive to future maintenance.

7. function
For a function in a program, the type of the function should be described before it is used, and the description of the function type must ensure that it is consistent with the type of function originally defined, with a "void" description for functions with no parameters and no return value type. If you need to shorten the length of your code, you can define some of the common program segments in your program as functions, as is the case with high-level optimizations in Keil. If you need to shorten the execution time of the program, the partial function is replaced with a macro definition after the program is debugged. Note that you should define the macro after the debugging of the program, because most of the compilation system will not complain after the macro is expanded, which can increase the difficulty of scheduling errors.

8. Use global variables as little as possible and use local variables more often.
Because the global variable is placed in the data memory, the definition of a global variable, the MCU is less than a available data memory space, if the definition of too many global variables, will cause the compiler does not have enough memory to allocate. And local variables are mostly located in MCU internal registers, in most MCU, register operation speed is faster than data memory, instruction is more flexible, it is advantageous to generate higher quality code, and the registers and data memory occupied by local variables can be reused in different modules.

9, set the appropriate compiler options
Many compilers have several different optimization options, and you should understand the meaning of each optimization option before you use it, and then choose the most appropriate optimization. In general, once the most advanced optimization, the compiler will be almost pathological pursuit of code optimization, may affect the correctness of the program, resulting in the program run error. You should therefore be familiar with the compiler you are using, and you should know which parameters are affected and which are not affected when tuning.
In Iccavr, there are two optimization options for "Default" and "Enable Code Compression".
In CodeVisionAVR, "Tiny" and "small" are two memory modes.
In IAR, there are 7 different memory mode options.
There are more optimizations in GCCAVR, and it's easier to choose inappropriate options.

Second, the Code optimization

1, choose the appropriate algorithm and data structure
Should be familiar with the algorithm language, know the advantages and disadvantages of various algorithms, specific data see the corresponding reference materials, there are many computer books are introduced. The slower sequential lookup method is replaced by a fast binary lookup or a sequence lookup method, which can greatly improve the efficiency of program execution by using the quick sorting, merging sort or root ordering instead. It's also important to choose a suitable data structure, For example, you use a lot of insertions and deletions in a bunch of randomly stored numbers, and it's much quicker to use a linked list.
Arrays and pointer statements have a very password relationship, in general, pointers are more flexible and concise, and the array is more intuitive, easy to understand. For most compilers, using pointers is shorter and more efficient than using arrays to generate code. But in Keil, in contrast, using arrays generates less code than the pointers you use.

3, use the small data type as far as possible
You can use a variable that is defined by character type (char) without using an integer (int) variable, and you can use an integer variable to define a variable that does not use a long int, and you do not use floating-point variables without using floating-point (float) variables. Of course, do not exceed the scope of the variable after the definition of variables, if the range of variables beyond the assignment, C compiler does not complain, but the program run the result is wrong, and such errors are difficult to find.
In the ICCAVR, you can set the printf parameter in options to use basic parameters (%c,%d,%x,%x,%u, and%s format specifiers) sparingly, with long integer parameters (%ld,%lu,%LX, and%LX format specifiers), as for floating-point parameters (%f) Try not to use it, the other C compilers are the same. With other conditions unchanged, using the%f parameter increases the number of generated code and slows execution.

4, the use of self-add, self-reduction instructions
It is often possible to generate High-quality program code using self-addition, self-subtraction directives and compound assignment expressions such as A-=1 and a+=1. Compilers are usually able to generate instructions such as Inc and Dec, and with instructions like a=a+1 or a=a-1, many C compilers generate two to three bytes of instruction. In the AVR monolithic application Iccavr, GCCAVR, IAR and so on the C compiler above several writes the code to generate is same, also can produce the high Quality The INC and the DEC and so on code.

5, reduce the strength of the operation
You can replace an expression that is complex by using an expression with a small amount of computation but the same functionality. As follows:

(1), residual operation.
a=a%8;
Can be changed to:
a=a&7;
Note: The bit operation can be completed with only one instruction cycle, while most of the C compiler's "%" operations are called subroutines to complete, code long, slow execution. In general, the only requirement for the remainder of the 2n is to use the bitwise manipulation method instead.

(2), square operation
A=pow (a,2.0);
Can be changed to:
A=a*a;
Note: In a microcontroller with built-in hardware multiplier (such as the 51 series), the multiplication operation is much faster than the square calculation, because the square of the floating-point number is realized by calling the subroutine, in the AVR MCU with the hardware multiplier, such as ATMega163, the multiplication operation can be done in only 2 clock cycles. Even in the AVR MCU without the built-in hardware multiplier, the subroutine of the multiplication operation is shorter than the subroutine code of the square operation, and the execution speed is fast.

If it is to ask for 3 times, such as:
A=pow (a,3.0);
Change to:
A=a*a*a;
The improvement of efficiency is more obvious.

(3), using shift to achieve multiplication and division method operation
a=a*4;
B=B/4;
Can be changed to:
a=a<<2;
b=b>>2;
Description: Usually if you need to multiply or divide by 2n, you can replace it with a shift method. In Iccavr, if multiplied by 2n, the left-shifted code can be generated, multiplied by the other integers or divided by any number, the multiplication and division procedures are called. Using the shift method to get code is more efficient than calling the code generated by the multiplication and division program. In fact, as long as it is multiplied or divided by an integer, the result can be obtained by a shift method, such as:
A=a*9
Can be changed to:
A= (a<<3) +a

6. Cycle
(1), Circulation language
For some tasks that do not require cyclic variables to participate in the operation can put them outside the loop, where the tasks include expressions, function calls, pointer operations, array access, etc., should be not necessary to perform multiple operations all together, put into an init initialization program.

(2), delay function:
     the commonly used delay functions are in the form of a self addition:
     void delay (void)
     {
unsigned int i;
     for (i=0;i<1000;i++)

     }
Change it to a self-reduced delay function:
     void delay (void)
     {
unsigned int i;
         for (i=1000;i>0;i--)

    }
Two functions have similar latency effects, but almost all C-compilation generates code that is less 1~3 than the previous one because almost all of the MCU has a 0-shift instruction that can be generated in the latter way.
when using a while loop, the use of the self-decrement instruction control loop is less 1~3 than the code generated by using the custom instruction control loop.
But in a loop where there is an instruction to read and write an array through the loop variable "I", it is possible to use a pre-minus loop to make the array hyper-bounded, and to draw attention to it.

(3) While loop and Do...while loop
The while loop has the following two types of loops:
unsigned int i;
i=0;
while (i<1000)
{
i++;
User Programs
}
Or:
unsigned int i;
i=1000;
Todo
i--;
User Programs
while (i>0);
In both loops, the code generated after compiling with the Do...while loop is shorter than the while loop.

7, check the table
In the program generally do not carry out very complex operations, such as the multiplication and division of floating-point numbers and the root, as well as some complex mathematical model interpolation operations, these are consuming time and resources of the operation, should try to use look-up table, and the data table placed in the program storage area. If it is difficult to generate the required table directly, as far as possible at the start of the calculation, and then in the data storage to generate the required tables, in order to run the program directly to check the table can be, reducing the program in the process of duplication in the calculation of the workload.

8. Other
For example, using online assembly and storing strings and some constants in program memory is beneficial to optimization.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.