A few weeks ago, we learn about gcc compiler and few of it's options, using these options your compiler will change/move your code around to make your code for better performance. I'm going to discuss about GCC compiler options which I researched on for my presentation for my Software Portability and Optimization course.
-ftree-dce is one of the option which I've chose for my research. -ftree-dce performs dead code elimination (DCE) on trees. This flag is enabled by default at -O and higher.
Example:
int main(){
int t = 5 + 5; //dead code
int r = 3 + 3;
printf(“Result is %d”, r);
}
In this example variable ‘t’ is considered a dead variable because it takes result of two numbers but the value of ‘t’ is never used. It isn't going to affect the final result so, calculating 5 + 5 and assigning the result to a variable will consume resources and space for something that can be avoided. Dead Code Elimination checks for conditions that will never be true and unnecessary calculations on variables which are not affecting the final result and it will remove that block of code before it converts the code into machine language which will provide better performance in your program by eliminating steps that are unnecessary.
Hence compiler option is enabled by default at -O level, so the dead code elimination option is always in use, unless you compile with –fno-tree-dce but still there are other similar options which eliminates dead code.
These are: -fdump-rtl-dce, -fdump-rtl-dce1, -fdump-rtl-dce2 and –ftree-builtin-call-dce which gives warning on unused variables it's default enabled at -O2
-fmove-loop-invariants is another compiler option which I've chose for my research. -fmove-loop-invariants enables the loop invariant motion pass in the RTL loop optimizer and its enabled at level -O1. Its purpose is to find any value or expression that remains the same on all iterations of the loop. By substituting out the expressions which are unchanged on all iteration the computer will have less number of operations to perform then original.
Example:
Loop invariants transform following code:
for (int i = 0; i < n; i++) {
x = y + z;
array[i] = 6 * i + x * x;
}
to:
Int x = y + z;
Int t = x * x;
for (int i = 0; i < n; i++){
array[i] = 6 * i + t;
}
Let's calculate number of operation in each code if n is 10. For untransformed code it will be 10 iterations * (2 for x=y+z + 4 for array[i] = 6 * i + x * x ) which is 60 operations and if we look at transformed code it will be 4 for code before loop + 10 iterations * (3 for array[i] = 6 * i + t) which is 34 operations. So, in small code as this we have almost half the number of difference and which means less processing for computer and you could have better performing applications.
Sunday, October 4, 2015
SPO600 Lab 2 - Examining compiler options
SPO600 - Lab 2
Modifying C program and compiling the program with gcc options and examining the output. Link to Lab is: SPO600_Compiled_C_Lab. Everything shown in this page has been ran on aarchie 64 machine.
Simple C - hello world program.
int main(){
printf("Hello World!");
}
Compiling Using: gcc -g -O0 -fno-builtin hello.c
Examining Executable File Using: objdump -f -s -d --source (executable filename)
Executable File Size: 9569 bytes
1. Add the compiler option -static. Note and explain the change in size, section headers, and the function call.
Executable File Size: 681707 bytes
Using the objdump command to determine changes gcc compiler did using -static option tell us that there was no changes made on how the main function is going to run, it just prevented linking with shared gcc libraries. This makes compiler copy all required information from gcc libraries to the executable file.
2. Remove the compiler option -fno-builtin. Note and explain the change in the function call.
Executable File Size: 9182 bytes
One small changed has been made in executable file, In original executable the printf() function is called to print
the line/it makes a one line function results in smaller and faster code but without -fno-builtin option the printf()
is using puts@plt option it puts printf() function on stack so it will be called later.
3. Remove the compiler option -g. Note and explain the change in size, section headers, and disassembly output.
Executable File Size: 8192 bytes
The executable file doesn't contain information on what each line does in main function, -g option adds debuggig information
to the executable file.
4. Add additional arguments to the printf() function in your program. Note which register each argument is placed in.
Executable File Size: 9456 bytes
Modified print line: printf("Helo World! %d, %d, %d, %d, %s, %f, %f, %f, %f, %s\n", 10, 20, 30, 40, "fifty", 59.99, 69.99, 79.99, 89.99, "Hundred");
I added multiple intergers, floats and strings arguments to printf funtion and the compiler uses ldr to create floating variables and fmove
pushes stores these variable into memory and adrp makes a string variables and add pushes/adds these varibles to memory.
5. Move the printf() call to a separate function named output(), and call that function from main(). Explain the changes in the object code.
Executable File Size: 9359 bytes
The executable file has few steps which is doing the same thing in both function like: stp and mov steps after function calls and
ldp and ret after function closing. Two bl (callq) are being made one to output function from main and then another to printf function
from output function these extras and repeting steps are made, for this scenario the function calls are too many then actucal task(printf) thats why this is inefficient. Having an extra function adds more work to the program and it provides less performance.
6. Remove -O0 and add -O3 to the gcc options. Note and explain the difference in the compiled code.
Executable File Size: 10616 bytes
The main function doesn't have the steps stp, mov, ldp and ret for main function because in main function is calling printf function and nothing else so the compiler doesn't save information about main function. Before it use to make callq to printf function and then comes back to main functions to finish its steps but now it just jumps to printf function and doesn't come back to make closing statements on main like ldp and ret because there isn't anything other then printf function so the return from printf function will go to operating system rather then going back to main function and main function returning to operating system. Option -O3 is optimized for program speed over memory space, the compiler will apply all optimiations to make it's speed better without worrying about memory space.
Modifying C program and compiling the program with gcc options and examining the output. Link to Lab is: SPO600_Compiled_C_Lab. Everything shown in this page has been ran on aarchie 64 machine.
Simple C - hello world program.
int main(){
printf("Hello World!");
}
Compiling Using: gcc -g -O0 -fno-builtin hello.c
Examining Executable File Using: objdump -f -s -d --source (executable filename)
Executable File Size: 9569 bytes
1. Add the compiler option -static. Note and explain the change in size, section headers, and the function call.
Executable File Size: 681707 bytes
Using the objdump command to determine changes gcc compiler did using -static option tell us that there was no changes made on how the main function is going to run, it just prevented linking with shared gcc libraries. This makes compiler copy all required information from gcc libraries to the executable file.
2. Remove the compiler option -fno-builtin. Note and explain the change in the function call.
Executable File Size: 9182 bytes
One small changed has been made in executable file, In original executable the printf() function is called to print
the line/it makes a one line function results in smaller and faster code but without -fno-builtin option the printf()
is using puts@plt option it puts printf() function on stack so it will be called later.
3. Remove the compiler option -g. Note and explain the change in size, section headers, and disassembly output.
Executable File Size: 8192 bytes
The executable file doesn't contain information on what each line does in main function, -g option adds debuggig information
to the executable file.
4. Add additional arguments to the printf() function in your program. Note which register each argument is placed in.
Executable File Size: 9456 bytes
Modified print line: printf("Helo World! %d, %d, %d, %d, %s, %f, %f, %f, %f, %s\n", 10, 20, 30, 40, "fifty", 59.99, 69.99, 79.99, 89.99, "Hundred");
I added multiple intergers, floats and strings arguments to printf funtion and the compiler uses ldr to create floating variables and fmove
pushes stores these variable into memory and adrp makes a string variables and add pushes/adds these varibles to memory.
5. Move the printf() call to a separate function named output(), and call that function from main(). Explain the changes in the object code.
Executable File Size: 9359 bytes
The executable file has few steps which is doing the same thing in both function like: stp and mov steps after function calls and
ldp and ret after function closing. Two bl (callq) are being made one to output function from main and then another to printf function
from output function these extras and repeting steps are made, for this scenario the function calls are too many then actucal task(printf) thats why this is inefficient. Having an extra function adds more work to the program and it provides less performance.
6. Remove -O0 and add -O3 to the gcc options. Note and explain the difference in the compiled code.
Executable File Size: 10616 bytes
The main function doesn't have the steps stp, mov, ldp and ret for main function because in main function is calling printf function and nothing else so the compiler doesn't save information about main function. Before it use to make callq to printf function and then comes back to main functions to finish its steps but now it just jumps to printf function and doesn't come back to make closing statements on main like ldp and ret because there isn't anything other then printf function so the return from printf function will go to operating system rather then going back to main function and main function returning to operating system. Option -O3 is optimized for program speed over memory space, the compiler will apply all optimiations to make it's speed better without worrying about memory space.
Subscribe to:
Posts (Atom)