When is assembly faster than C?

前端 未结 30 2379
挽巷
挽巷 2020-12-02 03:18

One of the stated reasons for knowing assembler is that, on occasion, it can be employed to write code that will be more performant than writing that code in a higher-level

相关标签:
30条回答
  • 2020-12-02 03:56

    Without giving any specific example or profiler evidence, you can write better assembler than the compiler when you know more than the compiler.

    In the general case, a modern C compiler knows much more about how to optimize the code in question: it knows how the processor pipeline works, it can try to reorder instructions quicker than a human can, and so on - it's basically the same as a computer being as good as or better than the best human player for boardgames, etc. simply because it can make searches within the problem space faster than most humans. Although you theoretically can perform as well as the computer in a specific case, you certainly can't do it at the same speed, making it infeasible for more than a few cases (i.e. the compiler will most certainly outperform you if you try to write more than a few routines in assembler).

    On the other hand, there are cases where the compiler does not have as much information - I'd say primarily when working with different forms of external hardware, of which the compiler has no knowledge. The primary example probably being device drivers, where assembler combined with a human's intimate knowledge of the hardware in question can yield better results than a C compiler could do.

    Others have mentioned special purpose instructions, which is what I'm talking in the paragraph above - instructions of which the compiler might have limited or no knowledge at all, making it possible for a human to write faster code.

    0 讨论(0)
  • 2020-12-02 03:56

    LInux assembly howto, asks this question and gives the pros and cons of using assembly.

    0 讨论(0)
  • 2020-12-02 03:58

    Short answer? Sometimes.

    Technically every abstraction has a cost and a programming language is an abstraction for how the CPU works. C however is very close. Years ago I remember laughing out loud when I logged onto my UNIX account and got the following fortune message (when such things were popular):

    The C Programming Language -- A language which combines the flexibility of assembly language with the power of assembly language.

    It's funny because it's true: C is like portable assembly language.

    It's worth noting that assembly language just runs however you write it. There is however a compiler in between C and the assembly language it generates and that is extremely important because how fast your C code is has an awful lot to do with how good your compiler is.

    When gcc came on the scene one of the things that made it so popular was that it was often so much better than the C compilers that shipped with many commercial UNIX flavours. Not only was it ANSI C (none of this K&R C rubbish), was more robust and typically produced better (faster) code. Not always but often.

    I tell you all this because there is no blanket rule about the speed of C and assembler because there is no objective standard for C.

    Likewise, assembler varies a lot depending on what processor you're running, your system spec, what instruction set you're using and so on. Historically there have been two CPU architecture families: CISC and RISC. The biggest player in CISC was and still is the Intel x86 architecture (and instruction set). RISC dominated the UNIX world (MIPS6000, Alpha, Sparc and so on). CISC won the battle for the hearts and minds.

    Anyway, the popular wisdom when I was a younger developer was that hand-written x86 could often be much faster than C because the way the architecture worked, it had a complexity that benefitted from a human doing it. RISC on the other hand seemed designed for compilers so noone (I knew) wrote say Sparc assembler. I'm sure such people existed but no doubt they've both gone insane and been institutionalized by now.

    Instruction sets are an important point even in the same family of processors. Certain Intel processors have extensions like SSE through SSE4. AMD had their own SIMD instructions. The benefit of a programming language like C was someone could write their library so it was optimized for whichever processor you were running on. That was hard work in assembler.

    There are still optimizations you can make in assembler that no compiler could make and a well written assembler algoirthm will be as fast or faster than it's C equivalent. The bigger question is: is it worth it?

    Ultimately though assembler was a product of its time and was more popular at a time when CPU cycles were expensive. Nowadays a CPU that costs $5-10 to manufacture (Intel Atom) can do pretty much anything anyone could want. The only real reason to write assembler these days is for low level things like some parts of an operating system (even so the vast majority of the Linux kernel is written in C), device drivers, possibly embedded devices (although C tends to dominate there too) and so on. Or just for kicks (which is somewhat masochistic).

    0 讨论(0)
  • 2020-12-02 03:58

    I'm surprised no one said this. The strlen() function is much faster if written in assembly! In C, the best thing you can do is

    int c;
    for(c = 0; str[c] != '\0'; c++) {}
    

    while in assembly you can speed it up considerably:

    mov esi, offset string
    mov edi, esi
    xor ecx, ecx
    
    lp:
    mov ax, byte ptr [esi]
    cmp al, cl
    je  end_1
    cmp ah, cl
    je end_2
    mov bx, byte ptr [esi + 2]
    cmp bl, cl
    je end_3
    cmp bh, cl
    je end_4
    add esi, 4
    jmp lp
    
    end_4:
    inc esi
    
    end_3:
    inc esi
    
    end_2:
    inc esi
    
    end_1:
    inc esi
    
    mov ecx, esi
    sub ecx, edi
    

    the length is in ecx. This compares 4 characters at time, so it's 4 times faster. And think using the high order word of eax and ebx, it will become 8 times faster that the previous C routine!

    0 讨论(0)
  • 2020-12-02 03:59

    It might be worth looking at Optimizing Immutable and Purity by Walter Bright it's not a profiled test but shows you one good example of a difference between handwritten and compiler generated ASM. Walter Bright writes optimising compilers so it might be worth looking at his other blog posts.

    0 讨论(0)
  • 2020-12-02 04:00

    Many years ago I was teaching someone to program in C. The exercise was to rotate a graphic through 90 degrees. He came back with a solution that took several minutes to complete, mainly because he was using multiplies and divides etc.

    I showed him how to recast the problem using bit shifts, and the time to process came down to about 30 seconds on the non-optimizing compiler he had.

    I had just got an optimizing compiler and the same code rotated the graphic in < 5 seconds. I looked at the assembly code that the compiler was generating, and from what I saw decided there and then that my days of writing assembler were over.

    0 讨论(0)
提交回复
热议问题