Why does an inline function have lower efficiency than an in-built function?

后端 未结 3 430
挽巷
挽巷 2021-01-03 20:59

I was trying a question on arrays in InterviewBit. In this question I made an inline function returning the absolute value of an integer. But I was told that my algorithm wa

3条回答
  •  猫巷女王i
    2021-01-03 21:23

    I don't agree with their verdict. They are clearly wrong.

    On current, optimizing compilers, both solutions produce the exact same output. And even, if they didn't produce the exact same, they would produce as efficient code as the library one (it could be a little surprising that everything matches: the algorithm, the registers used. Maybe because the actual library implementation is the same as OP's one?).

    No sane optimizing compiler will create branch in your abs() code (if it can be done without a branch), as other answer suggests. If the compiler is not optimizing, then it may not inline library abs(), so it won't be fast either.

    Optimizing abs() is one of the easiest thing to do for a compiler (just add an entry for it in the peephole optimizer, and done).

    Furthermore, I've seen library implementations in the past, where abs() were implemented as a non-inline, library function (it was long time ago, though).

    Proof that both implementations are the same:

    GCC:

    myabs:
        mov     edx, edi    ; argument passed in EDI by System V AMD64 calling convention
        mov     eax, edi
        sar     edx, 31
        xor     eax, edx
        sub     eax, edx
        ret
    
    libabs:
        mov     edx, edi    ; argument passed in EDI by System V AMD64 calling convention
        mov     eax, edi
        sar     edx, 31
        xor     eax, edx
        sub     eax, edx
        ret
    

    Clang:

    myabs:
        mov     eax, edi    ; argument passed in EDI by System V AMD64 calling convention
        neg     eax
        cmovl   eax, edi
        ret
    
    libabs:
        mov     eax, edi    ; argument passed in EDI by System V AMD64 calling convention
        neg     eax
        cmovl   eax, edi
        ret
    

    Visual Studio (MSVC):

    libabs:
        mov      eax, ecx    ; argument passed in ECX by Windows 64-bit calling convention 
        cdq
        xor      eax, edx
        sub      eax, edx
        ret      0
    
    myabs:
        mov      eax, ecx    ; argument passed in ECX by Windows 64-bit calling convention 
        cdq
        xor      eax, edx
        sub      eax, edx
        ret      0
    

    ICC:

    myabs:
        mov       eax, edi    ; argument passed in EDI by System V AMD64 calling convention 
        cdq
        xor       edi, edx
        sub       edi, edx
        mov       eax, edi
        ret      
    
    libabs:
        mov       eax, edi    ; argument passed in EDI by System V AMD64 calling convention 
        cdq
        xor       edi, edx
        sub       edi, edx
        mov       eax, edi
        ret      
    

    See for yourself on Godbolt Compiler Explorer, where you can inspect the machine code generated by various compilers. (Link kindly provided by Peter Cordes.)

提交回复
热议问题