How to optimize C Language Programs

Source: Internet
Author: User

Program optimization, usually refers to optimizing program code or program execution speed. Optimization code and optimization speed are actually a unity of yundun. Generally, optimizing the code size will increase the execution time. If the program execution speed is optimized, it usually brings the side effects of code increase. It is difficult to have both the fish and the bear's paw. You can only master a balance point during design.

I. Program Structure Optimization

1. Program writing structure
Although the writing format does not affect the quality of the generated code, you should follow certain writing rules when writing a program. A program with clear and clear writing is conducive to future maintenance. When writing a program, especially for While, for, do... While, if... Elst, switch... Case and other statements or nested combinations of these statements should be written in the form of "contraction,

2. identifier
Except for the naming rules of the identifiers, do not use algebraic symbols (such as a, B, x1, and y1) as variable names, english words (or abbreviations) or Chinese pinyin with relevant meanings should be selected as identifiers to increase the readability of the program, such as count, number1, red, and work.

3. Program Structure
C language is a high-level programming language that provides a complete and standardized process control structure. Therefore, when using C language to design Single-Chip Microcomputer Application System programs, we should first try to use structured programming methods, so that the entire application system program structure is clear, easy to debug and maintain. In a large application, the entire program is usually divided into several modules by function, and different modules complete different functions. Each module can be compiled separately or even by different programmers. Generally, the functions of a single module are relatively simple, and the design and debugging are relatively easy. In C, a function can be considered as a module. The so-called program modularization is not only to divide the entire program into several functional modules, but also to ensure the relative independence of variables between modules, this means that the independence of the module is maintained, and global variables should be used as little as possible. Some common functional modules can also be encapsulated into an application library so that they can be called directly when necessary. However, when modularization is used, if the module is too small, it will lead to lower execution efficiency of the Program (protection and recovery register takes some time to enter and exit a function ).

4. Define Constants
In the procedural design process, if some constants that are frequently used are directly written to the program, once the constant value changes, all constants in the program must be found one by one, and modify them one by one, which will inevitably reduce the maintainability of the program. Therefore, we recommend that you use preprocessing commands to define constants and avoid input errors.

5. Reduce judgment statements
Where Conditional compilation (ifdef) is available, Conditional compilation is used instead of if statements. This reduces the length of the code generated by compilation and reduces the number of statements used without judgment.

6. Expressions
Parentheses should be used to specify the priority of operations in an expression that are not clear or confusing. An expression cannot be written too complex. If the expression is too complex, it will not be easy to understand after a long time, which is not conducive to future maintenance.

7. Functions
Before using a function in a program, you should describe the function type. The description of the function type must be consistent with the previously defined function type, "void" should be added to functions without parameters or return value types. If you need to shorten the code length, you can define some common program segments in the program as functions, as is the high-level optimization in Keil. If you need to shorten the execution time of the program, some functions are replaced by macro definitions after the program debugging is completed. Note that the macro should be finalized after the program debugging is completed, because most compilation systems will report errors only after the macro is expanded, which increases the difficulty of troubleshooting.

8. Use as few global variables as possible, and use more local variables.
Because the global variables are stored in the data storage and a global variable is defined, the MCU has less space to use in the data storage. If too many global variables are defined, the compiler does not have enough memory to allocate. Most of the local variables are located in MCU registers. In most MCU, the Register operation speed is faster than the data storage device, and the instruction is more flexible, it is helpful to generate code with higher quality, and the registers and data storage occupied by local variables can be reused in different modules.

9. set appropriate compiler options
Many compilation programs have several different optimization options. before using them, you should understand the meaning of the optimization options and then select the most appropriate optimization method. In general, once the highest level of optimization is selected, the Compilation Program will pursue code optimization in a near-pathological manner, which may affect the correctness of the program and cause program running errors. Therefore, you should be familiar with the compiler in use and know which parameters will be affected during optimization and which parameters will not be affected.
In ICCAVR, there are two optimization options: "Default" and "Enable Code Compression.
In CodeVisionAVR, there are two memory modes: Tiny and small.
There are 7 different memory mode options in IAR.
There are more optimization options in GCCAVR, and it is easier to select inappropriate options accidentally.

Ii. code optimization

1. select an appropriate algorithm and Data Structure
You should be familiar with the algorithm language and know the advantages and disadvantages of various algorithms. For more information, see relevant references. Many computer books have introduced this. The slow sequential search method is replaced by the faster binary search or disordered search method, and the insert or bubble sort method is replaced by the fast sorting, Merge Sorting, or root sorting method, can greatly improve the efficiency of program execution .. It is also important to select a suitable data structure. For example, if you use a large number of insert and delete commands in a pile of Random storage numbers, it is much faster to use the linked list.
Arrays have a very password relationship with pointer statements. Generally, pointers are flexible and concise, while arrays are intuitive and easy to understand. For most compilers, using pointers is less efficient than using arrays to generate code. In Keil, however, the code generated using arrays is shorter than that using pointers ..

3. Use data types as small as possible
If you can use a variable defined by char, do not use an integer (int) variable. If you can use an integer variable to define a variable, do not use a long integer (long int ), do not use float variables without using float variables. Of course, after defining a variable, do not exceed the scope of the variable. If the value is greater than the scope of the variable, the C compiler does not report an error, but the program running result is wrong, in addition, such errors are hard to be found.
In ICCAVR, you can set the printf parameter in Options and try to use basic parameters (% c, % d, % x, % X, % u, and % s format specifiers ), use less long integer parameters (% ld, % lu, % lx, and % lX format specifiers). Do not use floating point parameters (% f). Do not use other C compilers. Using the % f parameter without changing other conditions will increase the number of generated codes and reduce the execution speed.

4. Use auto-increment and auto-increment commands
Generally, high quality program code can be generated using auto-increment, auto-increment, and composite value assignment expressions (such as a-= 1 and a + = 1, the compiler can usually generate commands like inc and dec, and use commands like a = a + 1 or a = A-1, many C compilers generate two to three bytes of commands. The code generated by the above writing methods is the same for the C compilers such as ICCAVR, GCCAVR, and IAR, which can also generate high-quality Code such as inc and dec.

5. Reduce the computing intensity
You can replace the original complex expressions with expressions that require a small amount of computing but have the same functions. As follows:

(1) perform the remainder operation.
A = a % 8;
You can change it:
A = a & 7;
Note: Bit operations can be completed in only one instruction cycle, while most of the C compiler's "%" operations are completed by calling subprograms. The code is long and the execution speed is slow. Generally, bitwise operations can be used to obtain the remainder of 2n.

(2) Square Calculation
A = pow (a, 2.0 );
You can change it:
A = a *;
Note: In a single-chip computer with a built-in hardware multiplier (such as the 51 series), the multiplication operation is much faster than the square operation, because the square operation of a floating point is achieved by calling a subroutine, in an AVR microcontroller that comes with a hardware multiplier, for example, in ATMega163, the multiplication operation can be completed with only two clock cycles. Even in an AVR Microcontroller without a built-in hardware multiplier, the subprogram of multiplication is shorter than the subprogram code of the square operation, and the execution speed is faster.

If the power is 3, for example:
A = pow (a, 3.0 );
Changed:
A = a *;
The efficiency improvement is more obvious.

(3) shift to realize multiplication and division
A = a * 4;
B = B/4;
You can change it:
A = a <2;
B = B> 2;
Note: If you need to multiply or divide by 2n, you can use the shift method. In ICCAVR, if it is multiplied by 2n, the code for left shifting can be generated. If it is multiplied by other integers or divided by any number, the multiplication and division subprograms are called. Using the shift method to obtain code is more efficient than calling the code generated by the multiplication and division subprograms. In fact, if it is multiplied by or divided by an integer, the result can be obtained by shift, for example:
A = a * 9
You can change it:
A = (a <3) +

6. Loop
(1) Circular Language
For tasks that do not require cyclic variables for calculation, you can put them out of the loop. The tasks here include expressions, function calls, pointer operations, and array access, put all the operations that are not necessary to be executed multiple times together in an init initialization program.

(2) latency functions:
The commonly used latency functions are in the form of auto-increment:
Void delay (void)
{
Unsigned int I;
For (I = 0; I <1000; I ++)

}
Change it to the auto-subtraction delay function:
Void delay (void)
{
Unsigned int I;
For (I = 1000; I> 0; I --)

}
The latency of the two functions is similar, but almost all C-compiled functions generate less code than the previous one ~ Three bytes, because almost all MCU commands have 0 transfer, the latter method can be used to generate such commands.
The same is true when a while loop is used. Using the auto-increment command to control the loop will produce less code than using the self-increment command to control the loop ~ 3 letters.
However, when reading and writing an array using the cyclic variable "I" in a loop, using a pre-subtraction loop may cause the array to be out of bounds.

(3) while loop and do... While Loop
When using a while LOOP, there are two types of loops:
Unsigned int I;
I = 0;
While (I <1000)
{
I ++;
// User program
}
Or:
Unsigned int I;
I = 1000;
Do
I --;
// User program
While (I> 0 );
In these two loops, do... The code generated after the while LOOP compilation is shorter than the while loop.

7. query table
In a program, it generally does not perform very complex operations, such as floating point multiplication and division, and some complex mathematical model interpolation operations, for these operations that consume time and resources, try to use the table query method and place the data table in the program storage area. If it is difficult to directly generate the required table, try to calculate it at startup, and then generate the required table in the data storage. Then, you can directly query the table by running the program, reduces the workload of repeated computing during program execution.

8. Others
For example, online assembly and saving strings and some constants in program memory are conducive 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.