When is assembly faster than C?

前端 未结 30 2394
挽巷
挽巷 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:43

    http://cr.yp.to/qhasm.html has many examples.

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

    Point one which is not the answer.
    Even if you never program in it, I find it useful to know at least one assembler instruction set. This is part of the programmers never-ending quest to know more and therefore be better. Also useful when stepping into frameworks you don't have the source code to and having at least a rough idea what is going on. It also helps you to understand JavaByteCode and .Net IL as they are both similar to assembler.

    To answer the question when you have a small amount of code or a large amount of time. Most useful for use in embedded chips, where low chip complexity and poor competition in compilers targeting these chips can tip the balance in favour of humans. Also for restricted devices you are often trading off code size/memory size/performance in a way that would be hard to instruct a compiler to do. e.g. I know this user action is not called often so I will have small code size and poor performance, but this other function that look similar is used every second so I will have a larger code size and faster performance. That is the sort of trade off a skilled assembly programmer can use.

    I would also like to add there is a lot of middle ground where you can code in C compile and examine the Assembly produced, then either change you C code or tweak and maintain as assembly.

    My friend works on micro controllers, currently chips for controlling small electric motors. He works in a combination of low level c and Assembly. He once told me of a good day at work where he reduced the main loop from 48 instructions to 43. He is also faced with choices like the code has grown to fill the 256k chip and the business is wanting a new feature, do you

    1. Remove an existing feature
    2. Reduce the size of some or all of the existing features maybe at the cost of performance.
    3. Advocate moving to a larger chip with a higher cost, higher power consumption and larger form factor.

    I would like to add as a commercial developer with quite a portfolio or languages, platforms, types of applications I have never once felt the need to dive into writing assembly. I have how ever always appreciated the knowledge I gained about it. And sometimes debugged into it.

    I know I have far more answered the question "why should I learn assembler" but I feel it is a more important question then when is it faster.

    so lets try once more You should be thinking about assembly

    • working on low level operating system function
    • Working on a compiler.
    • Working on an extremely limited chip, embedded system etc

    Remember to compare your assembly to compiler generated to see which is faster/smaller/better.

    David.

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

    I can't give the specific examples because it was too many years ago, but there were plenty of cases where hand-written assembler could out-perform any compiler. Reasons why:

    • You could deviate from calling conventions, passing arguments in registers.

    • You could carefully consider how to use registers, and avoid storing variables in memory.

    • For things like jump tables, you could avoid having to bounds-check the index.

    Basically, compilers do a pretty good job of optimizing, and that is nearly always "good enough", but in some situations (like graphics rendering) where you're paying dearly for every single cycle, you can take shortcuts because you know the code, where a compiler could not because it has to be on the safe side.

    In fact, I have heard of some graphics rendering code where a routine, like a line-draw or polygon-fill routine, actually generated a small block of machine code on the stack and executed it there, so as to avoid continual decision-making about line style, width, pattern, etc.

    That said, what I want a compiler to do is generate good assembly code for me but not be too clever, and they mostly do that. In fact, one of the things I hate about Fortran is its scrambling the code in an attempt to "optimize" it, usually to no significant purpose.

    Usually, when apps have performance problems, it is due to wasteful design. These days, I would never recommend assembler for performance unless the overall app had already been tuned within an inch of its life, still was not fast enough, and was spending all its time in tight inner loops.

    Added: I've seen plenty of apps written in assembly language, and the main speed advantage over a language like C, Pascal, Fortran, etc. was because the programmer was far more careful when coding in assembler. He or she is going to write roughly 100 lines of code a day, regardless of language, and in a compiler language that's going to equal 3 or 400 instructions.

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

    More often than you think, C needs to do things that seem to be unneccessary from an Assembly coder's point of view just because the C standards say so.

    Integer promotion, for example. If you want to shift a char variable in C, one would usually expect that the code would do in fact just that, a single bit shift.

    The standards, however, enforce the compiler to do a sign extend to int before the shift and truncate the result to char afterwards which might complicate code depending on the target processor's architecture.

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

    I have read all the answers (more than 30) and didn't find a simple reason: assembler is faster than C if you have read and practiced the Intel® 64 and IA-32 Architectures Optimization Reference Manual, so the reason why assembly may be slower is that people who write such slower assembly didn't read the Optimization Manual.

    In the good old days of Intel 80286, each instruction was executed at a fixed count of CPU cycles, but since Pentium Pro, released in 1995, Intel processors became superscalar, utilizing Complex Pipelining: Out-of-Order Execution & Register Renaming. Before that, on Pentium, produced 1993, there were U and V pipelines: dual pipe lines that could execute two simple instructions at one clock cycle if they didn't depend on one another; but this was nothing to compare of what is Out-of-Order Execution & Register Renaming appeared in Pentium Pro, and almost left unchanged nowadays.

    To explain in a few words, fastest code is where instructions do not depend on previous results, e.g. you should always clear whole registers (by movzx) to remove dependency from previous values of the registers you are working with, so they may renamed internally by the CPU to allow instruction execute in parallel or in different order.

    Or, on some processors, false dependency may exist that may also slow things down, like false dependency on Pentium 4 for inc/dec, so you may with to use add eax, 1 instead or inc eax to remove dependency on previous state of the flags.

    You can read more on Out-of-Order Execution & Register Renaming if time permits, there is plenty information available in the Internet.

    There are also other important issues like branch prediction, number of load and store units, number of gates that execute micro-ops, memory cache coherence protocols, etc., but the most important thing to consider is namely the Out-of-Order Execution.

    Most people are simply not aware about the Out-of-Order Execution, so they write their assembly programs like for 80286, expecting their instruction will take a fixed time to execute regardless of context; while C compilers are aware of the Out-of-Order Execution and generate the code correctly. That's why the code of such unaware people is slower, but if you will become aware, your code will be faster.

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

    You don't actually know whether your well-written C code is really fast if you haven't looked at the disassembly of what compiler produces. Many times you look at it and see that "well-written" was subjective.

    So it's not necessary to write in assembler to get fastest code ever, but it's certainly worth to know assembler for the very same reason.

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