Skip to main content
GameDev.net gamedev.net
🔒 Locked

ASM vs C

Started by afarnen Jan 15, 2008 at 12:53 AM 45 replies 16.6k views
Original Post
afarnen
afarnen
Hi, I ask simply, which do you think is better, Assembly (no specific architecture), or C (or any other high-level language)? I often hear assembly praised for its speed and performance, though languages such as C are often labeled as "easier to understand", or "easier to write". Though all assembly languages are different (x86, x64, ppc, arm), they all share the same idea: a low level language that translates directly into bytecode that the CPU can understand. I'm sure that it is not hard nowadays to create x86 assembly, and use some tool to cross-compile it into, say x64 assembly. However, languages such as C are looked at as more cross-platform. For instance, the "Hello, World!" program in (ANSI) C remains the same for all platforms, however, "Hello, World!" for x86 is different than "Hello, World!" for x64, or Power PC, or ARM, or any other architecture. Some choose to use languages such as C, or C++, Python, etc, along with inline assembly, a kind of compromise. However, I can imagine this method, just as pure assembly does, limits cross-compilation, though perhaps improving performance. Those are my reasons, what are your decisions? Please give your reasons as well.
skyfire360
skyfire360
FWIW, the only time I've really used assembly in the past few years is in GPU shaders (VS/PS 1.0), CPU capability detection via the CPUID instruction, and SSE/SSE2 SIMD instructions.

From the many articles I've read, most have said that as a general rule, the compiler can write better assembly than humans can.
I do real things with imaginary numbers
Spoonbender
Spoonbender
Quote:
Original post by afarnenI often hear assembly praised for its speed and performance


That's wrong. Languages don't have some kind of intrinsic "speed". Not even assembly languages.

How fast is C code? Exactly as fast as the code generated by the compiler. (and that depends on the code written by you)
How fast is assembly code? As fast as the code generated by the assembler. Which depends on the code written by you. It's extremely easy to write extremely slow assembly. In fact, it takes a lot of effort to *avoid* doing that.

With higher level languages, it's often harder to screw up so badly. The compiler tend to be better at optimizing and tweaking your code to produce something that doesn't perform *too* badly. With assembly, you generally get exactly the code you write. If you write bad code, you get bad performance.

In cases where you know more about what you're doing than the compiler does, you can usually write better (faster) assembly than what would be generated if you wrote in a high-level language.
But assembly isn't "faster". Or "slower", for that matter.
cignox1
cignox1
You don't say what you need it for, so giving an answer is not that easy.
First of all, asm is not necessarily faster than c: todays compiler use very advanced optimization techniques to speed up the generated code. You will need very high skills and a lot of experience to outperform compilers, and most probably you would need a lot of time to master say just one assembly, not to say more than one.
Second, inlining assembly into c source can be made cross platform using #ifdef directive. You write a generic c routine and as many asm versions as you want and simply put them in a #ifdef block to tell the compiler which one has to be used given a particular target machine. Note however that inline asm syntax (and availability) id compiler dependent. For example (IIRC) VC++ doesn't make inline asm available for 64bit processor, and you must use intrinsics to take advantage of the latest simd instructions (not really a bad thing though).
Last, not always all this performance is required. There are other aspetcs to take into consideration: other higher level languages make it harder to do certain types of errors and most have very complete libraries (see java, python or the .net api).
If you need to interface directly with the hardware I suggest to skip both asm and C and go directly with c++. If you need to build generic applications with GUI and net capabilities, then go with higher level language. I still use C++ a lot (for my raytracer for example), and I like it, but for tools and GUI application I would use other languages (C# is a good one, but python or java are equivalent choices):
afarnen
afarnen
Quote:
Original post by Spoonbender
Quote:
Original post by afarnenI often hear assembly praised for its speed and performance


That's wrong. Languages don't have some kind of intrinsic "speed". Not even assembly languages.

How fast is C code? Exactly as fast as the code generated by the compiler. (and that depends on the code written by you)
How fast is assembly code? As fast as the code generated by the assembler. Which depends on the code written by you. It's extremely easy to write extremely slow assembly. In fact, it takes a lot of effort to *avoid* doing that.

With higher level languages, it's often harder to screw up so badly. The compiler tend to be better at optimizing and tweaking your code to produce something that doesn't perform *too* badly. With assembly, you generally get exactly the code you write. If you write bad code, you get bad performance.

In cases where you know more about what you're doing than the compiler does, you can usually write better (faster) assembly than what would be generated if you wrote in a high-level language.
But assembly isn't "faster". Or "slower", for that matter.


you know what i meant. i meant that Assembly is often said to do jobs in less time, than when the same job is written by a compiler
LordJulian
LordJulian
I'm not much of an asm expert; heck, I'm not much of a programmer either (shhh, don't let the company that hired me as a programmer find out :p ), but it stands as is:

When you write an C/C++ program, the compiler must translate that into an equivalent assembler listing, that finally gets translated into bytecode that is chewed on by the CPU. When you write ths same program, only in asm, you skip a step.From that alone, it should sound like Asm is way better, as some things might be overcomplicated by the translation.

HOWEVER, when converting from C/C++ to Asm, the compiler if FREE to pull out all it's tricks on the code, as long as IT DOES THE SAME THING. Meaning it can replace MOV ax,0 into XOR ax,ax; both do the same thing, but it is a well known fact that the latter, though not so intuitive, is (or it was) faster. It does a whole lot more than that, but with a limit. It really doesn't know a lot about what is it that you're trying to do... It applies a whole bunch of optimisation (it's FASCINATING to look through an asm listing of compiled, OPTIMISED code; you can do that in visual studio for example, you can compile some program in release mode and in options you can check to have it save the asm listing WITH the original code lines as comments; do that, you will see)...

So, the same algorithm, written in C/C++ and then translated in a "dumb" way in Asm, will almost certainly work faster in C/C++; however, in ASM you can take some shortcuts if YOU REALLY REALLY REALLY know what your're doing (and screw everything up if you don't). Asm is a hell to debug (I have a coleague who might think otherwise, but he's the king of geeks :p ), C/C++ has A LOT of basecode. I personally go with C/C++ and don't regret it, while wanting to learn C# for gui stuff...

Ah, one more advantage, the new compilers can be made to compile code as to take advantage of the latest and greathest CPU "extensions" like MMX,SSE, SSE2. so on and so forth, maybe in manners that you wouldn't ever consider... It takes two life times to master all that...

Ah number 2, for small, isolated, very task specific and critical parts, like, say, matrix/vector arithmetics you may want, just as a hobby,try to write the fastest, most complete, flexible and fucnctional library using nothig more than asm and all the sse extensions...

Ah number 3, the CPU nowdays is a beast, doing something "wrong" in assambler MAY induce pipeline stalls which translate in lost time while the CPU tries to recover...

Ah number 4, the same CPU now rearanges your code while it runs, so there's a greath deal of optimisation there two, you, however, can break that too by writing sloppy asm code...

However, as a hobby, it's so ever nice to try and fiddle with it

I'm going now... Cheers

P.S. I may just be ranting and all of what I written may not be true :p
Kippesoep
Kippesoep
I've written quite a bit of ASM in the past and it is quite possible (and not even all that difficult IMHO) to write tighter and better code than a compiler. However... as compilers improve, the differences in efficiency are vanishingly small and ASM code, by its very nature, requires many more instructions to carry out even the simplest tasks. This makes ASM code several orders of magnitude more difficult to maintain (and even to comprehend when reading it). Therefore, it is often just not worth it. I can count the number of times I've used ASM last year on one hand. Wrote a few tiny .COM programs for DOS and did a few highly optimised inner loops for graphics processing code. One would have to be rather masochistic to write entire programs in ASM these days. It has its place when trying to squeeze every last CPU cycle out of a subroutine somewhere, but there are often many other ways to improve performance of your program. I like ASM, but it just doesn't seem worth the bother nowadays.
Kippesoep
jbadams
jbadams
Quote:
Original post by afarnen
Quote:
Original post by Spoonbender
Quote:
Original post by afarnenI often hear assembly praised for its speed and performance


That's wrong. Languages don't have some kind of intrinsic "speed". Not even assembly languages.[...]
you know what i meant. i meant that Assembly is often said to do jobs in less time, than when the same job is written by a compiler
That's precisely what he just explained to be false, you need to be very good at what you're doing to write assemly that does outperform a version compiled from a higher level language if you're using a good modern optimising compiler.

For general purposes, the concept of assembly "optimisation" is often a myth these days, and compilers are getting better and better at producing optimised code that can be very hard to outperform by any worthwhile margin if at all. For specific bottleneck cases or opportunities to use extended or optimised instruction sets you may get a more performant application if you know what you're doing.

Unless the code that you're writing is pretty trivial it'll probably take a lot more development time to produce the asm when compared to a higher level language. It can be done, but often isn't worth the effort.

Whether or not it would be worth implementing some functionality or an entire program in assembly is very situation specific though, and you'd not given us any specific scenario to work with.
- Jason Astle-Adams
d000hg
d000hg
Why are you describing C as a high-level language? C is more a medium-level language, it's really only one level above assembly.
RSC_x
RSC_x
hey asm is easy if you know it realy.//i assume it hawe direct access to anything or indirect to virtual devices.

so you can allways write your high lewel options by script in assembly.
but you cant modify somethings on high level allways.

so low level is better but just if you know anything you wil need[this means you may need also high level language knowldge.for simulating/copying them]
so low level can do anything directly.high level neds them built in and may be possible wia indirect ways.
i allways like d.m.a. type languages because they are realy programming.
using a function/mechanism without knowing its structure is not realy prefect as someones thinks and says out of there[or were saying in the time.?]

i'll give an example about what the high and low level means
high level you are using a driver and the driver where you want.
low level: you driving your car yourself.
so you can go where you want but some high levels are like bus driver and they do not follow your directions allways.

so prefer lov level if i know where i go and if i hawe map.
[i were trying to explain some basigs to non programmers before . so sorry if it looks too basic.]
© Loading...<font col
Hidden Asbestos
Hidden Asbestos
Don't forget that C compilers usually have an option to emit ASM code during compilation. You can use this to make both languages to work for you.

For speed critical sections you can look to see how the C compiler is dealing with your code on your target architecture. While coding in C It's often easy to create unnecessary constraints for the compiler to deal with. For example I once spotted that I had used an 8-bit type for a variable that didn't really need to be that size, yet the compiler had to honour my type choice and was creating extra ASM code to pack a 32-bit result into the 8-bit value.

As mentioned above trying to write code that works efficiently on a modern CPU would end up being hard to read. I would suggest that using ASM to guide your C coding may yield better results than a 100% hand-coded approach. Also remembering that effective optimisation is much more important than choice of language.
Antheus
Antheus
Hi, I ask simply, which do you think is better, Hammer (no specific size), or Screwdriver (or any other similar tool). I often hear hammer praised for its versatility, though tools such as screwdrivers are often labeled as "easier to hold".

Though all hammers are different, they all share the same idea. A blunt object that is used to pound things into place. I'm sure it's not hard nowadays to find hammers by the pound.

However, tools like screwdrivers are looked as more accurate and have more finesse. Some choose to use a whole toolbox (screwdrivers, power tools, shovels) along with hammers, a kind of compromise. However, I can imagine this method, just as using hammer alone, limits your ability to build different types of houses, although perhaps helps you build more sturdy houses faster.

....

See why your question doesn't make sense?

When was the last time you heard architects discussing whether to build Golden Gate with hammers only, or with a full toolbox?
stonemetal
stonemetal
most of the time when I use asm I start with the C version and get the listing, as has been stated earlier, then tweak it from there. It makes it so much easier to get started, and you don't have to write the entire section of code by hand.
ChaosEngine
ChaosEngine
Quote:
Original post by stonemetal
most of the time when I use asm I start with the C version and get the listing, as has been stated earlier, then tweak it from there. It makes it so much easier to get started, and you don't have to write the entire section of code by hand.


or if you've been programming at any time in the last 10 years:

most of the time when I use C++ I start with the python version and get it to work, as has been stated earlier, then profile the hell out of it. It makes it so much easier to get started, and you don't have to write assembly at all. ever.

OK, that's slightly tongue-in-cheek and I will concede that sometimes you need assembly (mostly on serverely resource-constrained embedded platforms), but in general it's unnecessary*.

To extend Antheus's analogy, if you wanted to build a house you could use a giant lump of stone and a chisel, bricks and mortar or prefabricated building components. Fair enough, the pre-fab components might not give you enough control to make the house you want, so use the pre-fabs where you can, and the bricks where you need to. But you still wouldn't actually chisel the house out of stone.


*hey if you want to write assembly for fun (you sick masochist[grin]) go nuts. Just don't delude yourself into thinking you're being productive.
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
janta
janta
.\ProgrammingLanguage.cpp(12) : error C2676: binary '>' : 'ProgrammingLanguage' does not define this operator or a conversion to a type acceptable to the predefined operator


Listen to The Man.
Hodgman
Hodgman
Quote:
Original post by Spoonbender
With higher level languages, it's often harder to screw up so badly. The compiler tend to be better at optimizing and tweaking your code to produce something that doesn't perform *too* badly.

That is, until you go too high, and start writing enterprisey code that no optimiser (human or compiler) can make run fast! ;)

I agree though that if you use the high-levels properly, then there's often no reason to use any low-levels unless you're doing specialist stuff (in which case, a low-level tool might be more suitable due to compiler unavailability or immaturity in the specific field).
ChaosEngine
ChaosEngine
Quote:
Original post by janta
.\ProgrammingLanguage.cpp(12) : error C2676: binary '>' : 'ProgrammingLanguage' does not define this operator or a conversion to a type acceptable to the predefined operator


Listen to The Man.


Sorry, but I can't agree. Yes, different languages for different jobs, but that doesn't mean that some languages aren't better than others. VB.net may not be a "better" language than java, but it's certainly better than VB6. Languages evolve and some ideas work better than others.
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
guywithknife
guywithknife
For anyone who thinks it's not hard to write more efficient assembly programs than those generated by a decent modern optimizing compiler, I'd just like to say that this is not really possible unless you have read and understand all of the Intel Optimization manual. Thats about 350 pages of material and it's not exactly an easy subject. To write truely efficient programs, you need to understand whats covered in this book fairly well.
I'd say most people can do that easy enough, but I'd wager that most people who write assembly to speed up some random program do NOT do this and therefore don't really know what they're doing and that most people who think "oh ill just write it in assembly" don't know the first thing about optimization in assembly and also that their time would be better spent doing something other than studying the optimization manual.

Just for a laugh, I opened up my copy... and quickly closed it again because I'd rather let the compiler worry about prefetching, optimal use of the cache, data packing, instruction parallelism and all the other things Intel want me to read about.

My point is basically that it takes a lot of work to write a truely optimal assembly program and that a modern compiler with good optimization can do this a lot better than you can without investing a ton of time and effort of learning about assembly optimizations. Because of this, I'd advise against it - instead you could use your time for something that gives a better return for your time and effort.



PS: I write a good bit of assembly myself, but then, only when it makes sense (when messing with kernel code (even then, only enough to let me do the rest in C) and when using microcontrollers - I like playing with wireless sensor networks and other nifty hardware stuff, but even then, I can often use a high level language).
SimonForsman
SimonForsman
Quote:
Original post by issch
For anyone who thinks it's not hard to write more efficient assembly programs than those generated by a decent modern optimizing compiler, I'd just like to say that this is not really possible unless you have read and understand all of the Intel Optimization manual. Thats about 350 pages of material and it's not exactly an easy subject. To write truely efficient programs, you need to understand whats covered in this book fairly well.
I'd say most people can do that easy enough, but I'd wager that most people who write assembly to speed up some random program do NOT do this and therefore don't really know what they're doing and that most people who think "oh ill just write it in assembly" don't know the first thing about optimization in assembly and also that their time would be better spent doing something other than studying the optimization manual.

Just for a laugh, I opened up my copy... and quickly closed it again because I'd rather let the compiler worry about prefetching, optimal use of the cache, data packing, instruction parallelism and all the other things Intel want me to read about.

My point is basically that it takes a lot of work to write a truely optimal assembly program and that a modern compiler with good optimization can do this a lot better than you can without investing a ton of time and effort of learning about assembly optimizations. Because of this, I'd advise against it - instead you could use your time for something that gives a better return for your time and effort.


It should ofcourse also be added that intels optimization guides doesn't tell you anything about how to optimize properly for AMD cpus (AMD has their own guides for that and yes, there are some significant differences), or future intel cpus, if you use a highlevel language you can simply tell your compiler to optimize for the architectures you are interested in, (and when a new cpu gets on the market you could simply update your compiler, recompile your code and you have a new optimized binary for that architecture aswell).

Thus i would say that the optimization guides released by Intel and AMD are of more interest to people who write compilers than it is to people who write applications/games.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
guywithknife
guywithknife
SimonForsman, yes, you are, of course, correct!
I was going to mention different processor versions, but then decided I wouldn't bother. I didn't think of AMD processors though, which is a good point!

I agree that the manual is of most use to compiler writers, but it makes sense for them to invest time into reading and learning from them, while it doesn't for your average programmer who wants to write assembly to speed up their code.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.