Atmocreations
Atmocreations

Reputation: 10071

ASM-optimizations lost after compilation?

Not that I'm in that situation currently, but I'm just interested in the answer...

Assuming you have some code written in C/C++ and you want to manually optimize it by modifying it in ASM.

What happens if you alter the code in C/C++ and recompile from source. Sure, the optimization on the just compiled file is lost. How do you avoid that these optimizations need to be redone each time the project is compiled? Do you create separate source files for the parts that need to be optimized to make it less complex? Or is there some kind of automatic tool to do this...? Guess you cannot use diff/patch for this...

Please share your experiences, thanks

Upvotes: 2

Views: 785

Answers (7)

Dmitry
Dmitry

Reputation: 6780

Sorry, not strictly an answer to your question, but I believe that people making compiler are a lot better in asm, than most of us. Thus I'd more rely on compiler doing "the right thing", rather than writing some asm code in the midst of c++ source.

Another argument for me for not using at least inline asm (yet sometimes I like to put an __asm int 3; in code) is that MS Visual Studio compiler doesn't support inline asm for 64 bit builds.

And one last thing, have you tried using a different algorithm for optimization, rather than assuming that say gcc (that can use SSE_whatever_is_the_current_version optimizations) produces asm code worse than you can write.

Upvotes: 2

Richard Pennington
Richard Pennington

Reputation: 19985

Another good reason for using inline assembly: gcc style inline assembly gives the code generator a bunch of information (clobbers, volatile, etc.) that the code generator can use to make your assembly fit nicely (and inline!) into your C/C++ code without losing opportunities for optimization.


Edit:

For example, the C code from another answer:

int main(void)
{
    int foo = 10, bar = 15;
    __asm__ __volatile__("addl  %%ebx,%%eax"
                         :"=a"(foo)
                         :"a"(foo), "b"(bar)
                         );
    printf("foo+bar=%d\n", foo);
    return 0;
}

produces:

....
movl    $15, %ebx
movl    $10, %eax
#APP
addl  %ebx,%eax
#NO_APP
movl    %eax, 8(%esp)
movl    $.str, (%esp)
movl    %eax, 4(%esp)
call    printf
....

The variables foo and bar are kept in registers and never even stored on the stack.

Upvotes: 2

Eli Bendersky
Eli Bendersky

Reputation: 273864

Do not modify the assembly code generated by your compiler. Modifying it, like modifying any auto-generated code is a very bad idea precisely for the reason you've discovered yourself.

If there is a particular portion of code you'd like to manually optimize by implementing it in ASM, you have two options:

  1. Write the code as ASM code in the first place, and link an assembled ASM file into your executable. You can first let the compiler generate assembly from C/C++ and then modify it, if this saves you time. But from this moment on manage this code at the ASM level.
  2. Use inline assembly in your C/C++ code. Since hand-optimized ASM portions of code are usually small, this is often the best idea. Using inline ASM is very simple in most compilers. Below is a simple snippet for GCC:

int main(void)
{
        int foo = 10, bar = 15;
        __asm__ __volatile__("addl  %%ebx,%%eax"
                             :"=a"(foo)
                             :"a"(foo), "b"(bar)
                             );
        printf("foo+bar=%d\n", foo);
        return 0;
}

It demonstrates nicely how to combine C code with ASM, sharing variables.

Upvotes: 4

Kornel Kisielewicz
Kornel Kisielewicz

Reputation: 57635

Instead of modifying the output, why don't you rewrite the critical sections of code in inlined assembler? The method how to do that varies between compilers -- check your compilers documentation.

In MSVC:

// asm_overview.cpp
// processor: x86
void __declspec(naked) main()
{
    // Naked functions must provide their own prolog...
    __asm {
        push ebp
        mov ebp, esp
        sub esp, __LOCAL_SIZE
    }

    // ... and epilog
    __asm {
        pop ebp
        ret
    }
}

In GCC:

 __asm__ ("movl %eax, %ebx\n\t"
          "movl $56, %esi\n\t"
          "movl %ecx, $label(%edx,%ebx,$4)\n\t"
          "movb %ah, (%ebx)");

Note also, that doing ASM changes AFTER compilation and optimization is something only for those that know EXACTLY what they are doing. Not only does the compiler optimize the structure in a way a human couldn't (at least not one without lighting calculator abilities), it also performs a much more complex analisys of the code that we could ever do.

Trust in your compiler. It's the greatest tool you'll ever work with ;).

Upvotes: 7

Nick Meyer
Nick Meyer

Reputation: 40422

If your compiler supports it, perhaps you are looking for something like inline assembly?

Upvotes: 3

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84239

You either link with modules explicitly written in assembler, or use inline asm.

Upvotes: 1

Tarydon
Tarydon

Reputation: 5213

You write some functions in a separate ASM file and call those functions from your C/C++ code. Or you write inline assembly directly in your C/C++ code.

In other words, you could start with some C/C++ code to get some basic ASM code, but after you start tweaking it, you delete the original C/C++ code and replace it with your ASM code, using one of these 2 methods.

Upvotes: 7

Related Questions