Optimize C ++ code (3) constant merge

Source: Internet
Author: User

This article is about constant merge, which is one of the simplest optimizations of the VC ++ compiler. This optimization means that the compiler directly calculates the expression results during compilation (during compilation) and replaces the expressions with the calculated results in the generated code. This avoids the cost of running these computations.

In the APP. cpp fileMainFunction:

 
 
  1. int main() { return 7 + 8; } 

First, some notes about this article:

If you want to continue, please refer to the instructions below. In fact, you only need to select a correct variant from the Visual Studio list.

Note: If you are using a free compiler on Visual Studio Express, it can only run on x86, but it will also generate x64 code smoothly. This experiment is also useful .)

We can use the command CL/FA App. cpp to build the sample program. Use the/FA switch to create an output file to save the compilation code generated by the compiler. You can enter type App. asm to display it:

 
 
  1. PUBLIC  main 
  2. _TEXT   SEGMENT 
  3. main    PROC 
  4.         mov     eax, 15 
  5.         ret     0 
  6. main    ENDP 
  7. _TEXT   ENDS 
  8. END 

Interestingly, this commandMove ax, 15-- Assign only 15 values to the Register EAX (according to the definition of x64 call standard, x64 function will setIntValue, used as the result of the function and returned to the caller ). The compiler does not issue 7-plus 8 commands during runtime. As shown below:

 
 
  1. PUBLIC  main 
  2. _TEXT   SEGMENT 
  3. main    PROC 
  4.         mov     eax, 7 
  5.         add     eax, 8 
  6.         ret     0 
  7. main    ENDP 
  8. _TEXT   ENDS 
  9. END 

Note: The last instruction of the two codes,Ret 0The control is returned to the caller and 0 bytes are displayed from the stack. Do not mislead the caller into believing that the return value is 0 !)

I guess you may be thinking: This is good, but which idiot would want to write 7 + 8 operations in the code? Indeed, you are right, but the compiler will regard this structure as a macro with side effects. After reading the example below, you will understand that constant merge is a useful optimization method:

 
 
  1. #define SECS_PER_MINUTE  60 
  2. #define MINUTES_PER_HOUR 60 
  3. #define HOURS_PER_DAY    24 
  4.   
  5. enum Event { Started, Stopped, LostData, ParityError }; 
  6.   
  7. struct { 
  8.     int        clock_time; 
  9.     enum Event ev; 
  10.     char*      reason; 
  11. }   Record; 
  12.   
  13. int main() { 
  14.     const int table_size = SECS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY * sizeof Record; 
  15.     // rest of program 

We need to create a table that is large enough to store records every second. Therefore, table_size is the table size, expressed in bytes. It is easy to view the Assembly command of the variable table_size:

 
 
  1. mov     DWORD PTR table_size$[rsp], 1382400     ; 00151800H 

There is no multiplication command here. 60*60*24*16 = 1382400 is calculated during compilation.

In fact, when we look into the compiler, we will find that the constant merge operation is very simple, and it is executed by the front end. The backend optimizer does not require heavy lifting capabilities. So it always exists. Whether you enable optimization or O2) or disable optimization or Od, the optimization is always automatically executed.

Can we merge constants during compilation regardless of the complexity of expressions? -In fact, the front-end can handle Arbitrary Constant arithmetic expressions and even include the sizeof mentioned above, as long as they are computed during compilation) and operators+-*/% <> ++ And-). You can even use boolean values, logical operators, AND conditional operators if AND? :.

Does constant merge require a backend optimizer? Of course, see the following example:

 
 
  1. int bump(int n) { return n + 1; }  
  2.    
  3. int main() { return 3 + bump(6); }  

Enter the command cl/FA/Od App. cpp and you will get the message: cannot optimize. Thank you !, Enter App. asm and we will get:

 
 
  1. mov     ecx, 6 
  2. call    ?bump@@YAHH@Z                           ; bump 
  3. add     eax, 3 

As we expected, ECX will save the first parameter 6, according to The x64 call convention, then call the bump function, and return the result to EAX, and then add 3 to EAX.

Let's see if we useCl/FA/O2 App. cppFor optimization, what will happen.

 
 
  1. mov eax,10 

The backend optimizer has recognized that the bump function is very small and can be included in the caller. We will discuss this optimization method in the following sections, called inline function ). It can estimate the value of the entire expression at compilation, with only one command left. Amazing, right?

Http://blog.jobbole.com/47191/.

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.