First of all, what is execution efficiency? What we usually call execution efficiency is the system overhead generated by using the same algorithm to complete the same calculation under the same input conditions. At present, we generally pay more attention to the overhead of execution time. All codes written in all languages must be converted into machine code to run in the end. The efficiency is high if the same thing can be completed in a shorter time.
Regarding how to improve the execution efficiency of C language programs, I would like to talk about my thoughts here based on my many years of programming experience:
1. Try to avoid calling delay functions
Programs without an operating system can only be executed in a while(1) loop. If a large number of delays are called in this loop, it will consume a lot of CPU resources. Delays are equivalent to letting the program rest and not do anything. Only the interrupts will be executed. If you just want to make a program that makes an LED flash once a second, it is very simple. You can directly call the delay function. However, in actual projects, there are often many things to do in a large loop, which is not possible for occasions with high real-time requirements. In order to avoid using delays, you can use a timer interrupt to generate a flag. When the time flag is set to 1, you only need to check the flag in the main program. Only when it is set to 1 will it be executed once, and then the flag will be cleared. At other times, you can do other things instead of waiting here. The best example is the display of the digital tube. The display is adjusted using interrupts. There is one in our routine. Then there is the key detection. Generally, programs are made to wait for the key to be released in while (! key). If the key is pressed all the time, the subsequent program will never be able to run and will die here. In fact, you can make a key flag to detect the falling edge and the rising edge to avoid this problem.
2. Write code as concisely as possible and avoid duplication
In the book "Learn MCU in 10 Days", I saw the code for the digital tube display. It selected a bit, then sent data, then selected another bit, then sent data, and so on. The code repetition rate is too high. It not only occupies too much class memory, but also has poor execution efficiency and poor readability. It just implements the function. The actual programming can be done in a loop, for loop or while loop. Such code looks more advanced.
3. Reasonable use of macro definitions
If a variable or register is frequently used in a program, you can use a macro definition to define a new name to replace it. The advantage of this is that it is easy to modify. For example, if the data bus of the LCD is connected to P1, and you now want to change it to P0, you only need to modify the macro definition here. When the compiler compiles, it will automatically replace the defined name with the actual name.
4. Use the smallest possible data type
For example, if the value range of a variable is 0-255, then define it as unsigned char. Of course, you can also define it as unsigned int, but this will waste memory and the efficiency of the operation will be lower. If there is no negative number in the data, try to define it as an unsigned type. Try to avoid defining it as a floating point data type or a double precision (occupying 8 bytes) type. These two types consume a lot of CPU resources when operating. For example, if the voltage range is 0-5v, accurate to three decimal places, you can expand the collected data by 1000 times, even if the maximum is only 5000, and then collect it several times to make a filtering algorithm. Finally, after the voltage is calculated, you only need to add a decimal point after the first digit. There is no problem if the variable is defined as an unsigned int variable.
5. Avoid using multiplication and division
Multiplication and division consume a lot of CPU resources. If you look at the assembly code, you will find that a multiplication and division operation will compile more than 10 or even dozens of lines of code. If you want to multiply or divide by a power of 2, you can use << or >> to implement it. This shift operation has been calculated at compile time, so the code is very concise and the operation efficiency is high. However, you need to pay special attention to the priority of operators.
6. Use compound assignment operators whenever possible
What is the difference between the two expressions a=a+b and a+=b? The former first calculates the value of a+b, then saves it to the ACC register, and then assigns the value of the ACC register to a, while the latter directly assigns the value of a+b to a, saving a step. Although it only saves one instruction, when this operation is repeated thousands or tens of thousands of times, the effect is very obvious. The other expressions -=, *=, /=, %=, etc. are the same.
7. Try not to define it as a global variable
Let's first look at the similarities and differences between local variables, global variables, static local variables, and static global variables:
(1) Local variables: variables defined in a function or compound statement, which are allocated storage units in the dynamic storage area, dynamically allocated when called, and automatically released when the function or compound statement ends;
(2) Static local variables: When defining a local variable in a function, if a static declaration is added, the variable is a static local variable, which is allocated a storage unit in the static storage area and is not released during program execution; static local variables can only be used in the function; static local variables are assigned values at compile time (if no value is assigned at definition time, the default value is 0 (for numeric variables) or a null character (for character variables)); static local variables are not automatically released after the function call ends, and the value after the function call ends is retained;
(3) Global variables: Variables defined outside a function are called global variables. Global variables are allocated storage units in the static storage area and are not released during program execution. All functions in the file can call the global variable. If functions in other files call global variables, they must be declared as extern.
(4) Static global variables: When defining a variable outside a function, if a static declaration is added, the variable is a static global variable. Static global variables are allocated storage units in the static storage area and are not released during program execution. Static global variables are assigned values at compile time (if no value is assigned at definition time, the default value is 0 (for numeric variables) or a null character (for character variables)). They can only be used in the current file.
Generally, they are defined as local variables, which not only runs more efficiently but also facilitates porting. Local variables are mostly located in registers inside the MCU. In most MCUs, register operations are faster than data memory, and instructions are more numerous and flexible, which is conducive to generating higher quality code. In addition, the registers and data memory occupied by local variables can be reused in different modules.
When the variable is needed in the interrupt, it needs to be defined as a global variable and modified with volume to prevent compiler optimization. If the data is read-only, such as the interrupt code of the digital tube and the font library of Chinese character modulus, it needs to be placed in ROM to save RAM. The 51 microcontroller adds code, and the advanced microcontrollers add const.
8. Choose the right algorithm and data structure
You should be familiar with algorithmic language and know the advantages and disadvantages of various algorithms. For specific information, please refer to the corresponding reference materials, which are introduced in many computer books. Replacing the slower sequential search method with a faster binary search or random search method, and replacing the insertion sort or bubble sort method with quick sort, merge sort or root sort can greatly improve the efficiency of program execution.
It is also important to choose a suitable data structure. A pointer is a variable that contains an address and can be used to address the variable it points to. Pointers can easily move from one variable to the next, so they are particularly suitable for situations where a large number of variables are operated. Arrays and pointer statements are closely related. Generally speaking, pointers are more flexible and concise, while arrays are more intuitive and easy to understand. For most compilers, the code generated by using pointers is shorter and more efficient than that generated by using arrays. However, in Keil, the opposite is true. The code generated by using arrays is shorter than that generated by using pointers.
9. Use conditional compilation
Generally, when compiling a C language program, all programs are compiled, but sometimes you want to compile only a part of it when certain conditions are met. This is conditional compilation. Conditional compilation can select different compilation ranges according to actual conditions, thereby generating different codes.
10. Embedded assembly - the killer feature
Assembly language is the most efficient computer language. In general project development, C language is generally used for development, because embedded assembly will affect the portability and readability of the platform, and assembly instructions on different platforms are incompatible. However, for some persistent programmers who require the program to achieve the ultimate running efficiency, they all embed assembly in C language, that is, "mixed programming". Note: If you want to embed assembly, you must have a deep understanding of assembly. Do not use embedded assembly unless it is absolutely necessary.
Previous article:Functions and characteristics of the parallel P3 port of the MCS-51 single-chip microcomputer
Next article:Analysis of the design ideas of the software watchdog of the single-chip microcomputer system
Recommended ReadingLatest update time:2024-11-16 13:32
- Popular Resources
- Popular amplifiers
- Wireless Sensor Network Technology and Applications (Edited by Mou Si, Yin Hong, and Su Xing)
- Modern Electronic Technology Training Course (Edited by Yao Youfeng)
- Modern arc welding power supply and its control
- Small AC Servo Motor Control Circuit Design (by Masaru Ishijima; translated by Xue Liang and Zhu Jianjun, by Masaru Ishijima, Xue Liang, and Zhu Jianjun)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- mini risc mcu source code
- The design application of TGA2509 is not particularly ideal
- Analysis of the problem that the program cannot run after F28004x online debugging reset
- Share a PD fast charging power deception chip CH224 is very practical
- Alloy sampling resistor series
- TI's Class AB car amplifier chip recommendations
- I am majoring in measurement and control, and am planning to work in the embedded system industry. Could you please tell me if this is the right major for me?
- MSP432E401Y MCU intelligent car speed measurement function
- Motor drive video
- Complementary PWM generation and dead zone control module of c2000