Slashdot Mirror


Why Learning Assembly Language Is Still Good

nickirelan writes "Why Learning Assembly Language Is Still a Good Idea by Randall Hyde -- Randall Hyde makes his case for why learning assembly language is still relevant today. The key, says Randall, is to learn how to efficiently implement an application, and the best implementations are written by those who've mastered assembly language. Randall is the author of Write Great Code (from No Starch Press)."

16 of 667 comments (clear)

  1. Debugging by Ann+Elk · · Score: 5, Insightful

    Another reason: Sooner or later, you'll need to debug something without a source-level debugger. Knowing how to debug raw assembly language has saved my ass many times.

    1. Re:Debugging by Percy_Blakeney · · Score: 5, Insightful
      Depending on where the heavy lifting is, Perl could easily outperform optimized C.

      But if Perl is written in C, wouldn't that mean that Perl can never be "faster" than C?

      To put it more concretely, couldn't I just write a program in C that does EXACTLY what the Perl program does, down to the last data structure? And if I did, wouldn't that mean that Perl can't ever (theoretically) be faster than C?

      You could even take it a step further. You could write an exact duplicate of the Perl program, leave out the parts of the Perl interpreter that you don't use, and you probably would end up with an overall faster program. Thus, in most cases, C could trump Perl.

  2. don't bother........ by Anonymous Coward · · Score: 5, Insightful

    Hate to say, but the kind of optimization you learn about by knowing assembly language is just not necessary for most programmers these days.

    I learned programming in the 80's, and I did learn assembly language, starting with 6502 assembly. I would subconciously code my C so that it would produce faster code. Every block of code I wrote would be optimized as much as practical. My code was fast and confusing.

    When coding Perl or Java I would keep in mind the details of the underlying virtual machine so I could avoid wasteful string concatenation or whatever. I cache things whenever possible, use temp variables all the time, etc., etc.

    I've spent the last few years trying to UNLEARN this useless habit. There is just no need. And in highly dynamic languages like Ruby, it's pointless. You can't predict where the bottlenecks will show up.. almost every project I've worked on has either had no performance problems, or had a couple major performance problems that were solved by profiling and correcting a bad algorithm.

    Stuff like XP and agile development have it right: code as simply as possible, don't code for performance, then when you need performance you can drill down and figure out how to do it.

    To me a beautiful piece of code is one that is so simple it does exactly what it needs, and nothing more, and it reads like pseudo-code. Minimalism is the name of the game.

    So my advice is, don't learn assembly language. Learn Lisp or another abstract language. Think in terms of functions and algorithms, not registers and page faults. Learn to program minimally.

    On another note, the tab in my Konqueror for this article reads: "Slashdot | Why Learning Ass...". Heh. :-)

    1. Re:don't bother........ by MBCook · · Score: 5, Insightful
      I disagree.

      I have seen FAR FAR too many students in my various college programing classes who think nothing of calling functions with 15 parameters and copies of large datastructures (not references) and other such things. I really think that assembly should be one of the FIRST things taught to future programmers. So many people I've run up against don't have any idea how computers work. Sure things are "mentioned" in classes, but so much is lost on them. Somthing as simple as "passing 2 things is much MUCH faster/easier than passing 10" don't get taught.

      By passing 10 things, their job is easy. That's all they see. They don't know about registers (other than they exist and are sorta like variables on the CPU). So they don't know that to pass 10 things you might put some in registers but the rest will have to be passed in memory (which is slow) as opposed to puting everything in registers (if at all possible) which is faster (especially for simple functions).

      The only problem with assembly is the catch-22 mentioned in the article: you have to do all sorts of "magic" to print out to the screen or read from the keyboard, which can be confusing. And it takes a while to get them up to the point where they can start to understand that magic. My school teaches assembly (sorta) on little 68HC12 development boards that have built in callable routines that perform things equivelent to printf and such, so there is little voodoo involved which is nice.

      I'm not saying assembly is neccessary, but I DEFINATLY think it's important for programers to learn how things work under the compiler. I have seen FAR too many hideous bits of code that no one who understood the underpinnings of assembly would never dream of.

      --
      Comment forecast: Bits of genius surrounded by a sea of mediocrity.
    2. Re:don't bother........ by Smidge204 · · Score: 5, Insightful

      So basically you don't have time to do it right, but you might have time to do it twice?

      Learning assembly isn't all about optimization, either. Being familiar with how the machine works right down to the core will make you a better programmer, peroid. Personally speaking, it also helps develop that zen like ability to "think like the computer", and that helps you program not just more efficiently but more effectively since you can think things out better. You can't tell me you're not a better programmer for having been exposed to it... it simply changes the way you think about the machine.

      It can also be argued that "beautiful" code has no bearing on performance. It's also the kind of "Oh performance isn't an issue anymore" and "make te source code pretty" thinking that we now need gigahert+ machines with 128MB RAM just to write a goddamn letter... it's really quite sad that so many programmers just let their applications fill the hardware vacuum they think their users will have, or should have, just because they didn't take an extra day to think about what they're doing and write their code a little more efficiently.
      =Smidge=

    3. Re:don't bother........ by Elladan · · Score: 5, Insightful
      While the general idea you're expressing - that people should understand how computers work to program them - is a good one, I think you're missing the point to a large degree.

      The things that are most important in performance are, generally speaking, algorithms. It's important to understand things like:
      • Cache - the computer operates faster on small working sets.
      • Algorithm efficiency - O(nlogn) is better than O(n^2) for most problems.
      • Latency - network or disk round trips are bad.

      Etc. The sort of thing you're proposing, with stuff like function call arguments, loop conditionals, etc. are micro-optimizations, and are very seldom worthwhile for programmers. Micro-optimizations are almost always best left to the compiler writers, who can, in effect, program them once and let everyone reap the benefits.

      Consider your example in particular: A function with 2 arguments instead of 10 isn't really faster. First off, it's only slower on an x86 - many architectures have these things called registers, which you can use for things like function arguments. Second, those function arguments are spilled to the stack just before the function call jump. This means they're extremely hot in the D$, and will hardly even be any more expensive than a register to reload at all. Third, if you break the big function into a lot of little ones, you're incurring more call overhead and more pressure on the I$. Fourth, breaking the function up causes multiple copies of the function prologues and epilogues, which will easily overwhelm the register spilling cost. Etc. etc. etc.

      In other words, those 10 arguments are only microscopically slower, and may even be faster!

      In this case, the student should avoid writing a function with 10 arguments if it makes the code clearer. The value of this sort of incredibly trivial micro-optimization is fundamentally dwarfed by the value of readable code - if the student can read her code, that means she'll have fewer bugs and can spend more time optimizing it. And that's what'll really make the program faster.

      You should only consider worrying about optimizations at this level if you've already optimized your program at an algorithm level fully, have profiled it, and determined some particular pieces are extremely dense hot-spots that need to be improved by hand. But if you're doing that, you may want to consider recoding the hot-spots in assembly anyway.

      These days, these sorts of hot spots tend to be media codecs, and the way to speed those up is to use SIMD instructions - which can only be used properly from asm. So even before worrying about these sorts of extremely tight micro-optimizations, you'd want to recode in assembly just to use the special vector instructions! And in asm, readability is even harder to obtain, so you'll probably avoid a lot of the sort of micro-optimizations a crazy compiler will do just so you can make sure the code works right.
  3. Yes and no... by Daniel_Staal · · Score: 5, Insightful

    While I learned assembly, and found it useful for learning to understand exactly how the machines think, I'm not sure I agree with his basic premise. Namely, that great code (code that is well designed for it's job, and easy to work with and under) is always the efficient code, in machine terms.

    The machine thinks one way. A human thinks in another. Code that is well designed for easy updating, and extending, is code that is easy for a human to understand. If that is not the most efficient way for the machine to do it, that may be the price for 'great' code in this project. (The ideal balance depends on the project, of course. A kernel should be machine-efficient, for example.)

    --
    'Sensible' is a curse word.
  4. Re:Schools not teaching assembly anymore by thegrassyknowl · · Score: 5, Insightful

    I was fortunate enough to learn assembly on a few architectures. Admittedly all of them are microcontrollers (PIC, AVR, HC11), but it really does force you to understand how the machine is working.

    Some of the more serious asselbly languages still scare the hell out of me though; have you ever looked at the assembly for the TI C6x DSPs? It took me quite a while to come to terms with something simple, and the C compiler can better use the 8 parallel execution units better than I can...

    --
    I drink to make other people interesting!
  5. I disagree by nacturation · · Score: 5, Insightful

    Efficiency in terms of coding is a wonderful art and I think it's still applicable today. Kernel-level routines, games, drivers, etc. all benefit from tight coding in assembly language.

    But let's be honest here. Computer Science 101: an efficient algorithm coded in an inefficient way will always beat out an inefficient algorithm coded by hand in 100% optimized assembly. I'll put my crudely coded Javascript quicksort algorithm against your finely honed 100% assembly bubblesort algorithm any day. Not only will my algorithm beat the pants off of your algorithm, but I'll also code it in far less time and with way fewer debugging sessions than you would. Also, the higher-level language you go, the better it is for security. How easy is it to introduce things like buffer overflows, array out of bounds, etc. errors in assembly? How easy is it to do that in Java, C#, etc.?

    So yes, writing in assembly language is still good and has its places. But let's keep it to those places, shall we?

    --
    Want to improve your Karma? Instead of "Post Anonymously", try the "Post Humously" option.
  6. So What? by tomblackwell · · Score: 5, Insightful

    Wow. You can crash a machine with assembly language.

    That may seem impressive to you (especially if you're fourteen), but the fact is that exploits can be done in almost any language.

    In other news, this doesn't have a hell of a lot to do with the posted article, either.

  7. The problem with assembly... by jafo · · Score: 5, Insightful

    Quoting: "the best implementations are written by those who've mastered assembly language".

    I haven't read this book, but I'd hope that there would be some pretty good justification of the above statement. I suspect that it's not, though. First of all, who defines what the "best implementation" is?

    As Knuth says, the first rule of program optimization is: "Don't do it". Trying to optimize a program when you're writing it leads to all sorts of problems including difficult to maintain code, increated time and budget required for the project, and often it's not even a hot spot anyway.

    I used to be very concerned about using making my code fast, but have (over the decades) decided that making it obvious is much more important than speed, particularly in the initial implementation. Profiling allows you to concentrate on the 20% of the code that the program is actually spending 80% of it's time in, instead of guessing where the hot spots are going to be.

    I've found that another benefit of using simpler code is that I'm more likely to throw away whole sections of simpler code and try radically different algorithms or mechanisms. More complicated code I find I'll try to just tweek instead of dumping wholesale. Randically different approaches can lead to 10x speedups where tweeks of existing code may give you 2x speedups, if you're lucky.

    Don't get me wrong, I'm all for trying different approaches. I'm not sure I would have come to the same conclusion I have now if I hadn't spent quite a long time trying to write optimized code. It was a very different world back then, but I know I wasted a lot of time optimizing code that didn't at all need it. It was an experience though.

    Sean

  8. Re:Smaller code? We can hope... by Just+Some+Guy · · Score: 5, Insightful
    Misuse of high level languages such as visual basic, as well as off the shelf components for everything, has led to a level of code bloat in todays applications that is inexcusable.

    You, sir, are insane. Much of my job involves pushing around regular expressions and hash tables (aka associative arrays aka dictionaries). I know several flavors of assembler on distinct hardware platforms (x86, 68k, 6502, MIPS) so I say this out of experience rather than fear of the unknown: I'd rather swallow my own tongue than write anything non-trivial in a low-level language.

    Seriously, a lot of people who know what they're doing have provided a huge library of functionality for me to pick and choose from. If I need to write a GUI app, I'll do it in Python with GTK or QT bindings. I am competent to build it in assembler, but why? It wouldn't be portable, it'd shave a very small amount of size from the end product (most of the project's resources are likely to be spent in the GUI libraries and not the core of the program), and would take 20 times longer than necessary.

    There are a very few areas where low-level languages make sense. I haven't touched any of them in years.

    --
    Dewey, what part of this looks like authorities should be involved?
  9. Counterpoint by Temporal · · Score: 5, Insightful

    This guy says "Efficiency Is the Key". This guy is wrong.

    With the incredible power provided to us by modern CPU's, efficiency is just about completely irrelevant for 99% of non-game applications. Think... when was the last time you thought "This word processor just doesn't respond to my keypresses fast enough." or "AIM takes way too long to open a new IM window."? The reason why these programs aren't getting "faster" (as the article complains) is because there is no way to do so. They spend 99.9% of their time waiting for user input already.

    Optimizing code which doesn't need optimization is Bad with a capital 'B'. When optimizing code, there is almost always a tradeoff between efficiency and maintainability. Efficiency often requires cutting corners, killing opportunities for future expansion, or, at the very least, writing ugly code. When that added efficiency does not lead to any noticeable benefit to the user, why do it?

    Now, granted, you shouldn't use an O(n) algorithm when an O(lg n) one exists to solve the same problem. However, knowing the difference between O(n) and O(lg n) has nothing to do with knowing assembly. The only benefits you can get out of knowing assembly are constant-multiplier speed increases. And, frankly, shaving off 50% of 0.1% CPU time used is not going to help much.

    Really, the speed of modern CPU's is sickening. I can't count the number of times I've written a piece of code, thought "This is going to be so slow...", then watched it execute near instantaneously. Even when running programs in a prototype programming language I'm working on -- which currently runs about 40x slower than C, because it's a crappy prototype -- this happens to me regularly. The only time your code is going to be noticeably slow is if you are processing a very, very large data set or you are using slow algorithms. In the former case, sure, knowing assembly will help, but such cases are extremely rare in typical applications. In the latter case, find a better algorithm.

  10. Problems with article by Percy_Blakeney · · Score: 5, Insightful
    I agree with the underlying premise that more programmers should learn an assembly language and the intimate details of how a computer works. However, I disagree with several part of the article.

    - He faults inefficient coding for the failure of software speed to keep up with CPU speed (or at least, its a "large part".) This is much less true than he lets on; Amdahl's Law means that the CPU is less and less responsible for the speed of an application, while things such as disk seek/transfer times, memory access times, and network latency all play huge roles in the speed of your computer's software.

    - He seems to think that it's not terribly hard to become an "efficient" assembly language programmer. Bzzt, wrong! In the modern era of superscalar architectures, pipelining, processor specific instructions, branch delays, and memory heirarchies, it takes a hell of a lot of knowledge and experience to beat the performance of a good compiler.

    - He apparently hasn't tried any large assembly language porting efforts lately. I'd love to see the effort involved in porting a large x86 assembly language program to a MIPS architecture, all the while maintaining that coveted "ultra-efficiency". The reality is that a good compiler can be reasonably efficient at porting a program to a new architecture, while a programmer usually isn't.

    - He also apparently hasn't tried debugging a large chunk of assembly code lately. It is a fact of life that it is very difficult to debug assembly. By using a high-level language, you are increasing the readability of your software, which tends to decreases the number of bugs.

    I could go on, but needless to say, I'm not impressed with the numerous assumptions and generalizations about assembly that he makes. Learning assembly will make your high-level programming better, and limited use of it can be appropriate, but using it all over the place is a huge mistake.

  11. Because you can't always trust compilers by soullessbastard · · Score: 5, Insightful

    One thing that many programmers take for granted these days is that compilers produce correct code nearly all the time. They've gotten really good over the years and are really a testament to the quality of compiler engineers. Even so...

    I've been a programmer for over a decade and I've always found the worst problems to debug are when the problems aren't in your code but in the compiler. Compilers are programs too and have their own bugs. They aren't always 100% accurate at generating correct machine code for your source. And until the compiler gets fixed in the next patch or rev, you may be stuck with broken code unless you switch compilers.

    Sometimes disassembly of the problem code and inlining correct assembly can be the difference between shipping a product or missing a deadline because you've spent months sitting around for the next compiler version to fix your problem for you.

    ed

  12. Absolutely by KidSock · · Score: 5, Insightful

    I didn't start programming until I was in my mid 20s (degree in Chemistry). I liked fiddling with Java but always felt uncomfortable about what was going on underneath the hood. So I took a few classes. The first was Computer Systems Architecture. We wrote a game in x86 assembler. That class completely opened up my understanding how programs actually worked. To understand the stack, the state machine nature of things, and memory was an awakening experience.

    Now (~5yrs later) I'm a fully capable programmer and an even better designer. My preference is C, binary file formats, networking protocols, crafting elegant solutions for multiplexing IO. I'm lead on a project used in production by many companies large and small.

    I genuinely feel assembler is a vital part of the learning process for a programmer.