4 Replies - 432 Views - Last Post: 04 June 2017 - 09:27 AM

#1 DonSlowik  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 10
  • Joined: 19-March 16

Seeking advice on best compile flags for nice assembly in GDB

Posted 02 June 2017 - 03:44 PM

Applied to main.c below,
gcc -g main.c
allows gdb breakpoint setting, stepping, but 'messy'(as described above) code.
gcc -g -O1 main.c
allows gdb breakpoint setting, stepping, but first 'step' is to end of program! as it's all 'optimized out'.


main.c:
#define R 5
#define S 9
#define T 11

int A[R][S][T];

int store_ele(int i, int j, int k, int *dest) {
    *dest = A[i][j][k];
    return sizeof(A);
}

int main(void) {
    int ret;
    int i = store_ele(2, 3, 1, &ret);
    return i;
}



Where is the happy medium?

Elaboration:

I have found that, looking at the .s file produced by gcc -g -m64, that there tends to be alot of extraneous write/reads to/from memory, vs keeping things in registers. This is because -O0 optimization is defaulted to here. So I am talking esp x86-64 where function arguments are passed via registers, and it seems a waste the write/reads done vs working with those integers in registers. Using gcc -O1(2,3) -m64 generates much cleaner code (for the cases I'm talking about), but can only view the .s file directly as the symbol tables gdb needs are not being generated. So I tried gcc -g -O1, and gdb has the symbol tables (i guess) so i can step, but seems all the machine instructions are "optimized out" so single instructions stepping is often meaningless. I guess, in order to step through the machine instructions with gdb, alot of variables need to have a presence in memory.

So, bottom line, seems that GDB is best with gcc -g ---gives pleasant debugger stepping but extraneous memory inefficiencies.
Whereas gcc -O1 gives nice clean assembly code, but can't be stepping with the debugger through it, must just read the .s file.

Also, I use Qt IDE often, but I don't think that changes anything I've said here about how gcc/gdb behave.

If anyone else has been through similar path, and can offer some advice, greatly appreciated.

Is This A Good Question/Topic? 0
  • +

Replies To: Seeking advice on best compile flags for nice assembly in GDB

#2 Salem_c  Icon User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 2130
  • View blog
  • Posts: 4,196
  • Joined: 30-May 10

Re: Seeking advice on best compile flags for nice assembly in GDB

Posted 03 June 2017 - 01:52 AM

Why do you need any -O flags when you're trying to debug anyway?
You're stepping through the code line by line, why are you worried by a few 'memory inefficiencies'?

Debugging is for helping you establish the functional correctness of the program.
-O flags are for getting the best performance, after you have determined that it's working correctly.

The only time this becomes an issue is if you suspect there is a bug in the way the compiler has optimised the code. But more often than not, this is because there is a bug in your code, because it steps out of the 'defined behaviour' of the language. A favourite example of which is the use of side-effect.

But if you insist, perhaps

Quote

-Og Optimize debugging experience. -Og enables optimizations that do not interfere with debugging. It
should be the optimization level of choice for the standard edit-compile-debug cycle, offering a
reasonable level of optimization while maintaining fast compilation and a good debugging experience.

Was This Post Helpful? 0
  • +
  • -

#3 DonSlowik  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 10
  • Joined: 19-March 16

Re: Seeking advice on best compile flags for nice assembly in GDB

Posted 03 June 2017 - 03:32 PM

View PostSalem_c, on 03 June 2017 - 01:52 AM, said:


Thanks your reply. At this point, I'm stepping through the assembly generated by the compiler for the purpose of learning assembly, how C/C++ translates into assembly. My main purpose is so, in the future, when I encounter bottlenecks, I can look at the assembly for clues as to what my C++ is doing, then modify the C++ to remove the bottleneck if possible. I don't plan to write my own assembly. It's interesting to see that gdb will not single step through every line of assembly at some optimizations as i described. In those cases, seems one would have to resort to looking at the .s file.

I've read about sequence points before and have the main idea. That huge post of yours with many examples of how it plays out in actual programs will be fun to go through when i get a chance soon. thanks for having posted all that too.
Was This Post Helpful? 0
  • +
  • -

#4 Salem_c  Icon User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 2130
  • View blog
  • Posts: 4,196
  • Joined: 30-May 10

Re: Seeking advice on best compile flags for nice assembly in GDB

Posted 03 June 2017 - 11:20 PM

You find bottle-necks by using a profiler, not looking at the innards of the generated code one instruction at a time.

Big performance improvements come from choosing the right algorithms and data structures. No amount of peering at the assembler of bubble sort will ever fix your problem when you know that you should have used quicksort to begin with.

Also, the assembler that the compiler generates is the result of 100's (possibly 1000's) of years of distilled experience of turning high level languages into assembler. Many of the old tricks (like replacing a*2 with a<<1) have long been done by compilers (and so many more you would never realise).

If you want the compiler to generate the best code, then write plain straight-forward code.
#include <stdio.h>

void foo ( int x, int y ) {
  int temp = x;
  x = y;
  y = temp;
  // the optimiser realises what is going on and simply
  // reorders the call parameters
  printf("X=%d, Y=%d\n", x, y );
}
        subq    $8, %rsp
        movl    %edi, %ecx
        movl    %esi, %edx
        movl    $.LC0, %esi
        movl    $1, %edi
        movl    $0, %eax
        call    __printf_chk
        addq    $8, %rsp
        ret

void bar ( int x, int y ) {
  // an awful undefined behaviour which confuses the optimiser
  // enough to cause it to leave it alone.
  x ^= y ^= x ^= y;
  printf("X=%d, Y=%d\n", x, y );
}
        subq    $8, %rsp
        xorl    %esi, %edi
        movl    %edi, %edx
        movl    %esi, %ecx
        xorl    %edi, %ecx
        xorl    %ecx, %edx
        movl    $.LC0, %esi
        movl    $1, %edi
        movl    $0, %eax
        call    __printf_chk
        addq    $8, %rsp
        ret

int main ( ) {
  foo(1,10);
  bar(1,10);
  return 0;
}


The lesson here is if you gum up the works with your own preconceived (or simply out-dated) ideas of how to write optimised code, then the compiler may fail to make the best optimisations possible.
Was This Post Helpful? 0
  • +
  • -

#5 DonSlowik  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 10
  • Joined: 19-March 16

Re: Seeking advice on best compile flags for nice assembly in GDB

Posted 04 June 2017 - 09:27 AM

View PostSalem_c, on 03 June 2017 - 11:20 PM, said:


I've always agreed with those points which you raised.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1