Program Optimization Method (C/C ++)

Source: Internet
Author: User

 

Optimization of programs 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 about 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. The writing structure of the program, although the writing format does not affect the quality of the generated code, should follow certain writing rules in actual programming, A clear and clear program 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 "shrink". 2. The user identifiers used in the identifier program should follow the naming rules of the identifiers, generally, do not use algebraic symbols (such as a, B, x1, and y1) as variable names. Select English words (or abbreviations) with meanings or Chinese pinyin 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 the C language to design the Single-Chip Microcomputer Application System Program, pay attention to the use of structured programming methods as much as possible, 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 maintain the relative independence of variables between modules, that is, to maintain the independence of modules, use as few global variables 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. For some constants that are frequently used, if you write them directly to the program, once the constant value changes, it is necessary to find all constants in the program 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 the length of the code generated by compilation by using Conditional compilation instead of if statements where the judgment statement can use Conditional compilation (ifdef. 6. When the priority of operations in an expression is unclear or confusing, parentheses should be used to specify their priority. 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. Before using a function in a program, you should describe the function type. The description of the function type must be consistent with the original 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 you should define the macro after the program debugging is completed, because most compilation systems only report errors 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 the registers in the MCU. In most MCU, the Register operation speed is faster than that in the data storage, and the instruction is more flexible, which facilitates the generation of code with higher quality, in addition, the registers and data storage occupied by local variables can be reused in different modules. 9. Set the appropriate compiler options. Many compilers have several different optimization options. You should understand the meaning of each optimization option before use, 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. Be familiar with the algorithm language and know the advantages and disadvantages of various algorithms. For more information, see references, many books on computer science have been introduced. 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 quick sort, merge sort, or root sort, 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 pointers. 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. 2. Do not use INTEGER (int) variables to define variables that can be defined by char when the data type is as small as possible; do not use long integer (long int) for variables that can be defined using integer variables. Do not use floating-point variables without float. 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, and 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. 3. the auto-increment and auto-increment commands generally use the auto-increment and auto-increment commands and the composite value assignment expressions (such as a-= 1 and a + = 1) can generate high-quality program code, the compiler usually can generate inc and dec and other commands, and use a = a + 1 or a = A-1 and other commands, 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. 4. To reduce the computing intensity, you can replace the original complex expressions with a small amount of computing but the same functions. (1) perform the remainder operation. A = a % 8; can be changed to: a = a & 7; Note: Bit operations can be completed in only one instruction cycle, in most C compilers, the "%" operation is 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 operation a = pow (a, 2.0); can be changed to: a = a * a; note: in a single-chip microcomputer with built-in hardware multiplier (such as 51 series ), the multiplication operation is much faster than the square operation, because the square Calculation of floating point numbers is achieved by calling subprograms. In the AVR microcontroller that comes with the hardware multiplier, for example, ATMega163, the multiplication operation can be completed in only two clock periods. 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 it is to calculate the power of 3, for example, a = pow (a, 3.0); change to: a = a * a; then the efficiency improvement is more obvious. (3) shift to realize multiplication and division operations a = a * 4; B = B/4; can be changed to: a = a <2; B = B> 2; note: generally, If You Want To multiply by or divide by 2n, you can use the shift method instead. 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 the shift method. For example, a = a * 9 can be changed to a = (a <3) + a5, loop (1), loop language for some tasks that do not require cyclic variables to participate in calculation, you can put them out of the loop, the tasks here include expressions, function calls, pointer operations, array access, etc. All the operations that are not necessary to be executed multiple times should be combined and put into an init initialization program. (2) latency function: the commonly used latency function uses 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 ;);} 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... When a while loop is used, there are two types of loops: unsigned int I; I = 0; while (I <1000) {I ++; // user program} or: unsigned int I; I = 1000; doi --; // user program while (I> 0); in these two cycles, use do... The code generated after the while LOOP compilation is shorter than the while loop. 6. Look-up Tables generally do not perform very complex operations in the program, such as floating point multiplication, division, and square, and some complex mathematical model interpolation operations, for these operations that consume time and resources, you should 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. 7. For example, online assembly and saving strings and some constants in program memory are conducive to optimization.

Related Article

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.