It won't die because it's true, at least in some cases.
The LuaJIT 2.0 interpreter, written in x86-64 assembly language, is 2-5x the speed of the plain Lua interpreter, written in C. Note that this is with the JIT disabled -- it is an apples-to-apples comparison of interpreter-vs-interpreter: http://luajit.org/performance_x86.html
> What is your evidence in support of the idea that assembly cannot be faster?
I made no such claim.
My gripe was using it as a feature, claiming that since it's in assembly, it's certainly faster, which is just simply not true. In most cases, it's the algorithm that determines performance as opposed to the details of its implementation. Assembly certainly has its place, but arguing a kernel completely implemented in assembly is faster simply due to the abstraction level they're working on does not carry much weight. Of course you'll be able to find hand-tuned algorithms that are much faster in assembly than a higher-level language, but that does not follow that "Complex software written in X is generally slower than complex software written in assembly"
Also, Lua is a poor example. It's performance was much more heavily influenced by portability and embedability.
Of course, if you take two different pieces of software and implement one in assembly language, and the other in high level, you can't claim valid comparison.
But if you take one algorithm and implement it in both languages, assembly implementation will always be faster, thus the basis for their claim.
That's equivalent to claiming Assembly is always faster than other languages, because every program is just an algorithm. It's completely incorrect - I guarantee you I can write an implementation of an algorithm in Assembly that is slower than the same algorithm implemented in Ruby.
I think the person is trying to point out it is you need to be a good programmer to write good assembly, and the a assumption that you will always have a good programmer can be broken sometimes. An algorithm may be an algorithm, but sometimes an inexperienced programmer could easily make it slower.
I don't know, I always found the notion that humans will always be able to optimize better than machines to be somewhat... naïve. Is it an NP complete problem our own heuristics are currently better at estimating?
No one has performed controlled studies on these things - maybe they had some crummy bottlenecks, used some language feature that their compiler couldn't optimize away, maybe the benchmarks they use to determine performance are trivial (which is very often the case), etc.
Not to mention that most of an operating system's time, post boot is spent doing... what? Having the scheduler swap processes in and out? If you're running a single program that fits inside ram... it's totally fucking pointless, there's nothing left to optimize.
I have a better question. These guys are clearly smart. What the hell are they still doing in Atwood, Ontario?
> Is it an NP complete problem our own heuristics are currently better at estimating?
Some of the important problems are NP-complete (like register allocation). Another problem is that compilers aren't that good at telling fast-paths from slow-paths (and keeping everything in registers for the fast paths). For more info see this message from the author of LuaJIT: http://article.gmane.org/gmane.comp.lang.lua.general/75426
I think the problem is that optimization is AI-complete. Without a lot of context about what your program is doing under what circumstances the problem is not solvable. You need to know when and how a specific code path is run.
Agreed, I guess that when we have build smarter compilers a Centaur approach would work best (like in chess). The computer can do a whole lot by bruteforce and smart algorithms and the human uses his knowledge of the context to steer it in the right direction.
> What is your evidence in support of the idea that assembly cannot be faster?
I don't think that is the key, they key is the cost of that speed improvement. Say you spend a week to write the protobuf decoder in assembly so now it can decode in 30usec instead of 60usec. So you have an impressive 2x speed gain.
But then say, you are writing the data do a disk. Well maybe it doesn't really matter how fast you are decoding the protobuf if next you are sitting there for ages waiting for that data to be written out. That 30usec gain is nothing on top of that 10msec wait time that is coming next, so was that week a good investment f you just did for pure speed improvement? (well you might have done as a learning exercise, then speed doesn't really matter).
Although this is a valid point in many cases, I don't think this is one of those cases. It's in these "infrastructure" type projects like kernels, compilers, interpreters, and parsers where "micro" optimizations are actually really important.
> But then say, you are writing the data do a disk. Well maybe it doesn't really matter how fast you are decoding the protobuf if next you are sitting there for ages waiting for that data to be written out. That 30usec gain is nothing on top of that 10msec wait time that is coming next, so was that week a good investment f you just did for pure speed improvement? (well you might have done as a learning exercise, then speed doesn't really matter).
haberman's parser (1460 MB/s) outperforms Google's C++ parser (260 MB/s) more the 5x. Note that even in the disk example, a fast SSD will have enough bandwidth to throttle the CPU on Google's parser.
On top of that, this is FOSS, which means his weeks of investment is multiplied every time someone downloads and uses his code.
> On top of that, this is FOSS, which means his weeks of investment is multiplied every time someone downloads and uses his code.
Excellent point.
Also, I didn't mean to talk specifically about his parser, it was just used as a general example.
It is just that in my experience, engineers (I am guilty too) have a tendency to spend time micro-optimizing without, in the end, making a difference in overall user-experience. For example, stuff like choosing to write a GUI app in C++ when it could have been whipped up in Python in a fraction of time and lines of code. The menus will open in 10ms instead of 3ms but maybe it doesn't really matter from user
s point of view.
Same holds for most data that ends up in IO choke-points. Even memory today in SMP architectures is a choke-point. Spend time hand-optimizing CPU bound code only to find out that it ends up waiting on a lock, in a disk, network buffer, or for some user input.
Also micro-optimizations are often not future-proof. Many cache-friendly data structures and algorithms for example, assume a particular cache line size, or particular characteristics of hardware that just happen to change. Even in the assembly case, today we have 32bit, 64bit and ARM common target architectures, each with various levels of SSE extension support and other features, so one can spend a lot of time, maintaining and tweaking all of them.
In this case though, they say their market is for HPC clusters and embedded computing, which are two areas where most processes are likely to be CPU-intensive.
An interpreter isn't a fair comparison though - in assembly you can use a few tricks like threaded code (http://en.wikipedia.org/wiki/Threaded_code) to get a big speed boost, but these techniques aren't really broadly applicable to programs generally.
And in any case, it's still not an argument for writing an entire OS in assembly, but rather only a few important segments of the code.
LuaJIT has both an interpreter (written in assembly) and a JIT. The 2-5x I quoted is only for the interpreter (ie. with the JIT disabled). The speedup for the actual JIT is 2-130x vs. the interpreter written in C.
The Lua C implementation seems very conservatively written for portability and maintainability, but it's not slow either.
Handwritten assembly really can be faster than compiler generated code. The proof is that we can always look at the output of the compiler and invest more time improving on it by hand, whereas the compiler is required to complete in a short amount of time and usually without actually timing its code on the target machine.
Now if you take someone experienced in hand-tuning assembly like that and ask them to write the fastest possible code using a compiler, they're going to beat the pants off an ordinary coder who hasn't been benchmark everything he writes all along.
But the real lesson here is that Lua is just freaking awesome.
The LuaJIT 2.0 interpreter, written in x86-64 assembly language, is 2-5x the speed of the plain Lua interpreter, written in C. Note that this is with the JIT disabled -- it is an apples-to-apples comparison of interpreter-vs-interpreter: http://luajit.org/performance_x86.html
I recently wrote a protobuf-decoding assembly code generator that is 2-3x the speed of C++ generated code: http://blog.reverberate.org/2011/04/25/upb-status-and-prelim...
What is your evidence in support of the idea that assembly cannot be faster?