Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the compiler do in assembly when optimizing code? ie -O2 flag

So when you add an optimization flag when compiling your C++, it runs faster, but how does this work? Could someone explain what really goes on in the assembly?

like image 305
atkayla Avatar asked Nov 21 '13 02:11

atkayla


People also ask

What does compiler flag do?

Compile-time flags are boolean values provided through the compiler via a macro method. They allow to conditionally include or exclude code based on compile time conditions. There are several default flags provided by the compiler with information about compiler options and the target platform.

What is Flag in compiling?

Flags to Specify SIMD Instructions Creates an executable that uses SIMD instructions based on the CPU that is compiling the code. Additionally it includes the optimizations from the -mtune=native flag. -march=arch. This will generate SIMD instructions for a particular architecture and apply the -mtune optimizations.

What does flag in GCC do?

By default, GCC limits the size of functions that can be inlined. This flag allows the control of this limit for functions that are explicitly marked as inline (i.e., marked with the inline keyword or defined within the class definition in c++).

Does Java compiler optimize code?

The JVMs JIT compiler is one of the fascinating mechanisms on the Java platform. It optimizes your code for performance, without giving away its readability. Not only that, beyond the “static” optimization methods of inlining, it also makes decisions based on the way that the code performs in practice.


1 Answers

It means you're making the compiler do extra work / analysis at compile time, so you can reap the rewards of a few extra precious cpu cycles at runtime. Might be best to explain with an example.

Consider a loop like this:

const int n = 5;
for (int i = 0; i < n; ++i)
  cout << "bleh" << endl;

If you compile this without optimizations, the compiler will not do any extra work for you -- assembly generated for this code snippet will likely be a literal translation into compare and jump instructions. (which isn't the fastest, just the most straightforward)

However, if you compile WITH optimizations, the compiler can easily inline this loop since it knows the upper bound can't ever change because n is const. (i.e. it can copy the repeated code 5 times directly instead of comparing / checking for the terminating loop condition).

Here's another example with an optimized function call. Below is my whole program:

#include <stdio.h>
static int foo(int a, int b) {
  return a * b;
} 


int main(int argc, char** argv) {
  fprintf(stderr, "%d\n", foo(10, 15));
  return 0;
}

If i compile this code without optimizations using gcc foo.c on my x86 machine, my assembly looks like this:

movq    %rsi, %rax
movl    %edi, -4(%rbp)
movq    %rax, -16(%rbp)
movl    $10, %eax      ; these are my parameters to
movl    $15, %ecx      ; the foo function
movl    %eax, %edi
movl    %ecx, %esi
callq   _foo
; .. about 20 other instructions ..
callq   _fprintf

Here, it's not optimizing anything. It's loading the registers with my constant values and calling my foo function. But look if i recompile with the -O2 flag:

movq    (%rax), %rdi
leaq    L_.str(%rip), %rsi
movl    $150, %edx
xorb    %al, %al
callq   _fprintf

The compiler is so smart that it doesn't even call foo anymore. It just inlines it's return value.

like image 111
yamafontes Avatar answered Oct 21 '22 23:10

yamafontes