Checking compiler optimizations in gcc / g ++ by analyzing assembly lists

I just asked a question related to how the compiler optimizes certain C ++ code , and I looked for SO for any questions on how to verify that the compiler performed certain optimizations. I tried to look at the assembly generated with g ++ ( g++ -c -g -O2 -Wa,-ahl=file.s file.c ) to see what happens under the hood, but the output is too cryptic for me. What methods are used by people to solve this problem, and are there good links to how to interpret assembly lists of optimized code or articles specific to the GCC toolchain that talk about this problem?

+9
c ++ c assembly compiler-construction micro-optimization
Jan 06 '10 at 22:26
source share
8 answers

Optimization GCC transfers the work on an intermediate representation of your code in GIMPLE format.

Using the -fdump-* option family , you can ask GCC to display intermediate tree states.

For example, submit this to gcc -c -fdump-tree-all -O3

 unsigned fib(unsigned n) { if (n < 2) return n; return fib(n - 2) + fib(n - 1); } 

and watch how it gradually turns from a simple exponential algorithm to a complex polynomial algorithm. (Really!)

+18
Jan 06 '10 at 23:18
source share

A useful method is to run code under a good sampling profiler, for example. Zoom under Linux or Instruments (with the Time Profiler tool) on Mac OS X. These profilers not only show you the hot spots in your code, but also the map source code for the disassembled object code. Highlighting the source line shows (not necessarily contiguous) lines of generated code that map to the original line (and vice versa). Links to the online code and optimization tips are a good bonus.

+4
Jan 18
source share

Not gcc, but when debugging in Visual Studio you have the opportunity to group the assembly and the source, which gives a good idea of ​​what was created for which instruction. But sometimes it is not quite correctly aligned.

The output of the gcc and objdump -dS does not have the same granularity. This article about getting gcc to output source and assembly has the same options as you.

+3
Jan 06
source share

Adding the -L option (for example, gcc -L -ahl ) may provide somewhat more comprehensible lists.

The equivalent option is MSVC /FAcs (and it is slightly better because it interleaves the source, machine language and binary and includes some useful comments).




About one third of my job is to do what you do: juggle with C code and then look at the assembly to make sure it is optimized correctly (which is preferable to just write the built-in assembly all over the place).

Blogs and articles for game development can be a good resource for this topic, because games are real-time applications in read-only memory - I have a few notes on it , so Mike Acton and others. I usually like to keep the instructions for installing Intel instructions in the window while browsing the lists.

The most useful thing is to first get a good idea about programming the assembly at ground level, not because you want to write assembly code, but because by doing this, make reading much easier. I had a hard time finding a good modern textbook.

+2
Jan 07
source share

The scale with RotateRight ( http://rotateright.com ) is mentioned in another answer, but in order to expand it: it shows you the mapping of the source to the assembly in what they call a “code browser”. This is incredibly convenient, even if you are not an asm specialist, because they also integrated the documentation assembly into the application. And the assembly list is annotated with comments and deadlines for several types of CPUs.

You can simply open your object or executable with Zoom and see what the compiler has done with your code.

+1
Jun 09 2018-10-06T00:
source share

To display the applied optimizations you can use:

-fopt-info optimized

To view those that have not been applied

-fopt-info skipped

Remember that the output is sent to the standard error stream, so to see it , you really need to redirect this : (hint 2> & 1)

Here is a good example:

 g++ -O3 -std=c++11 -march=native -mtune=native -fopt-info-optimized h2d.cpp -o h2d 2>&1 h2d.cpp:225:3: note: loop vectorized h2d.cpp:213:3: note: loop vectorized h2d.cpp:198:3: note: loop vectorized h2d.cpp:186:3: note: loop vectorized 

You can check for alternating output by using -g with objdump -dS|c++filt , but that will not give you this. Enjoy it!

+1
Jan 05 '16 at 10:38
source share

Victor, in your case, the optimization you are looking for is simply a smaller allocation of local memory on the stack. You should see less distribution when entering the function and less release when the function exits if the space used by the empty class is optimized.

As for the general question, I have read (and written) assembly language for more than (gulp!) For 30 years, and all I can say is that it requires practice, especially to read the compiler output.

0
Jan 06 '10 at 23:18
source share

Instead of trying to read the assembler dump, run your program inside the debugger. You can pause execution, follow one-step instructions, set breakpoints on the code you want to test, etc. Many debuggers can display your C source code along with the generated assembly so that you can more easily see what the compiler has done to optimize your code.

In addition, if you are trying to test a specific compiler optimization, you can create a short dummy function that contains the type of code that corresponds to the optimization you are interested in (and nothing more, the simpler, the easier the assembly is to read). Compile the program once with optimization and once with them; comparing the generated assembly code for a dummy function between assemblies should show you what the compiler optimizers did.

0
Jan 07
source share



All Articles