views:

276

answers:

7

How is assembly faster than compiled languages if both are translated to machine code. I'm talking about truly compiled languages which are translated to machine code? Not C# or Java which are compiled to an intermediate language first and then compiled to native code by a software interpreter etc.

In Wikipedia, I found something which I'm not sure if its in any way related to this. Is it because that translation from a higher level language generates extra machine code? Or is my understanding wrong?

A utility program called an assembler is used to translate assembly language statements into the target computer's machine code. The assembler performs a more or less isomorphic translation (a one-to-one mapping) from mnemonic statements into machine instructions and data. This is in contrast with high-level languages, in which a single statement generally results in many machine instructions.

+2  A: 

An assembly expert may be able to write assembly code that is more effective (less instructions, more efficient instructions, simd, ...) than what a compiler generates automatically.

However, most of the time, you're better off trusting the optimizer of your compiler.

Learn what your compiler does. Then let the compiler do it.

Gregory Pakosz
Moreover, an assembly export will be able to fully use the processor's registers and instruction extensions, to perform most of the computation without accessing external memory, thus providing a noticeable boost. Of course, it depends if you target one or more processor...
Laurent Etiemble
@Laurent: and it also depends on your compiler. There's no reason a specialized compiler couldn't do that.
Martinho Fernandes
+1 for that last paragraph.
Martinho Fernandes
I thought about linking those slides. That's actually a nice collection of clever tricks compilers know about but many people who try writing assembly for performance reasons don't.
Joey
The trouble (and reason for writing assembly) is that there are lots of things the compiler could do but doesn't.
Crashworks
The trouble with a lot of people writing assembly is that they often do it even before profiling their application :)
Gregory Pakosz
+18  A: 

Well, it relates a bit to your question, indeed. The point is that compilers produce inefficient machine code at times for various reasons, such as not being able to completely analyze your code, inserting automatic range checks, automatic checks for objects being null, etc.

On the other hand if you write assembler code by hand and know what you're doing, then you can probably write some things much more efficient than the compiler, although the compiler's behavior may be tweaked and you can usually tell it not to do range checking, for example.

Most people, however, will not write better assembler code than a compiler, simply because compilers are written by people who know a good deal of really weird but really cool optimizations. Also things like loop unrolling are usually a pain to write yourself and make the resulting code faster in many cases.

While it's generally true that everything that a computer executes is machine code, the code that runs differs greatly depending on how many abstraction levels you put between the machine and the programmer. For Assembler that's one level, for Java there are a few more ...

Also many people mistakenly believe that certain optimizations at a higher abstraction layer pay off at a lower one. This is not necessarily the case and the compiler may just have trouble understanding what you are trying to do and fail to properly optimize it.

Joey
That means that assembly code may not be usually faster than compiled code (C/C++) ?
hab
Hand-written assembly code can be faster than compiled code if you *know what you're doing*. Most of the time, it won't.
Martinho Fernandes
Depends on the person who's writing it. See yu_sha's answer which nicely summarizes that. Compilers actually have fixed sets of rules how to write certain things more efficiently; those were ultimately created by people. People who may eb able to adapt those things to other situations as well and produce more efficient code than a compiler can. But in many many cases the compiler is much better at such things. For those snippets where it fails you can still resort to inline assembler but don't be surprised if it runs slower than the orignal code if you switch to a better/newer compiler.
Joey
I usually compare it to the difference between a car with a manual transmission or an automatic transmission. People say that a manual transmission gets better fuel economy, and that is true *if the driver is very skilled*, because it gives him better control, and that control allows a skilled driver to shift in the best way. If the driver does not know exactly what he is doing, then that finer control means he will actually do a worse job than the automatic would have.
Crashworks
@Crashworks: Great analogy. I do feel like writing bad assembly when I'm driving :(
Martinho Fernandes
@Crashworks: But driving with an automatic transmission is not nearly as exciting...
PhiS
It's fairly easy btw to take a disassembly of compiled code, handoptimize the assembler a bit while benchmarking and outdo the compiler. It is harder to do this for all 40000 procedures.
Marco van de Voort
+1  A: 

First - assembler should be used only in small code pieces, which eat most of CPU time in program - some kind of calculations for example - in "bottle neck" of algorithm. Secondly - it depends on experience in ASM of those who implements the same code in Assembler, if assembler implementation of "bottle neck" code will be faster. If experience is low - it will be slower. And contain a lot of bugs. If experience is high enough - ASM will give significant profit.

And pointing out that "If experience is high enough" is rarer than most people think: compilers are smarter than most people who think themselves smarter than the compiler.
Martinho Fernandes
+6  A: 

Assembly may sometimes be faster than compiled language if an assembly programmer writes better assembly than that generated by compiler.

Compiled language is often faster than assembly because programmers who write compilers usually know CPU architecture better than regular programmers.

yu_sha
It's they other way around: Handwritten assembly is often slower than a compiled source, because the wannabe assembler programmer just don't has a clue.
drhirsch
+1  A: 

First of all, compilers generate very good (fast) assembly code.

It's true that compilers can add extra code since high order languages have mechanisms, like virtual methods and exceptions in C++. Thus the compiler will have to produce more code. There are cases where raw assembly could speed up the code but that's rare nowdays.

Nick D
+2  A: 

My standard answer when questions about assembly vs. high-level come up is to take a look at Michael Abrash's Graphics Programming Black Book.

The first couple of chapters give a good idea of what you can optimise effectively using assembly, and what you can't.

You can download it from GameDev - Jeff's links seem to be broken now unfortunately.

Mike Houston
+1  A: 

All good answers. My only additional point is that programmers tend to write a certain number of lines of code per day, regardless of language. Since the advantage of a high-level language is that it lets you get more done with less code, it takes incredible programmer discipline to actually write less code.

This is especially an issue for performance because it matters almost nowhere except in a tiny part of the code. It only matters in your hotspots - code that you write (1) consuming a significant fraction of execution time (2) without calling functions (3).

Mike Dunlavey