I'm not sure that operating systems are so suited to ASM optimization (in the sense that you may not reap so many benefits). Maybe one could optimize for size (so you can make super tiny OS) ?
I'm not sure that operating systems are so suited to ASM optimization (in the sense that you may not reap so many benefits). Maybe one could optimize for size (so you can make super tiny OS) ?
In Java, that might involve adding more classes and abstractions to make things conceptually simpler. In C, that might involve using structs to keep relevant data together. In C++, it might involve using a std::set to keep a list of 3 constants, Etc.
It turns out that when you have to write the asm by hand and you see that double pointer dereference is a pain, you avoid data structures with double dereferences (as C data structures often end up with). You avoid classes and abstractions (as are common in Java), because they involve a lot of boilerplate. You use compile time constants for that set of three things rather than any complex hashing that C++ would do, etc.
There are lots of small things like this, and it turns out the effect adds up significantly.
I strongly disagree :-)
My experience is that optimizing assembler leads to reorganize your code or even your algorithm into a form that you'll CPU will be most efficient at executing which almost always translate to unbelievably intricate, super hard to modify code. I've done stuff on 6502, 80x86, MMX and the assembly parts, optimized for speed and ended up with impossibly tricky code. Worst, sometimes I have to adapt my data structures to allow optimization, which becomes even tougher. So, I prefer to leave assembly code at the "onyl if necessary" level
But now, to be honest, optimizing assembly code is incredibly satisfying to me :-) I've got the feeling to use a CPU to its maximum capacity. Also, using assembly comes after thorough algorithmic study. So once I'm at the ASM level, I've maxed out my own capabilities ! How happy me !
So if you have the chance to do that, just give it a try !
I'd assume that when you maintain larger codebases (i.e. full OS and application suite), that you start writing practical and maintainable code instead.
But even so, I'd say that ASM doesn't help. Clumsy code in ASM is worse than clumsy code in high-level language :-)
It's not subliminal. It's packing a backpack that someone else has to carry, vs packing a backpack that _you're_ going to carry.
I do not know, to be honest.
I was just pointing that multimedia and game engines can get a lot of helps on ASM by hand.
There are some SIMD constructs that you can efficiently express in C by writing intrinsics, but that isn't substantially different from writing ASM.
Then there are some trivial cases where a loop can be unrolled and packed into SIMD instructions automagically, which retains readability, but greatly limits what you can write. You'll need to read the generated machine code to make sure you didn't mess up.
The benefit of just writing ASM is to not have such a translation layer between you and the processor. That same code that you carefully wrote to make it through the optimization passes for one compiler will likely get messed up in another compiler.
Frankly, no.
Improving the compiler could get a few dozen of %, which is huge already. But 300%+, no.
Maybe one could optimize for size (so you can make super tiny OS) ?
Yes, and remember... optimizing for code size is optimizing for speed. =)Smaller code and data = more CPU cache hits, which are orders of magnitude faster than fetching from RAM. So even if "all" you do is make code smaller, you can get more speed...
Not always. I think loop-unrolling is a common perf-optimisation technique. Even if the perf-gain is positive in this case, I highly suspect that it doesn't outweigh the cost of maintaining asm code(vs C/other higher level code).
edit: formatting
Now we have CPUs with 256KB instruction cache and up. You can compile your whole OS at insane optimizations.
That's what created multi-kilobyte memcpy() implementations, which barely beat REP MOVSB but cause huge icache bloat.
Until the day the compiler can smartly trim down all the unity framework to just 512 bytes because it notices I'm not using most of it, hand coding in asm will always work out smaller and faster, if one puts in enough effort.
If you compile hello world in C, it's not going to be very big either.
> if one puts in enough effort
"enough effort" is a cheat. I can replace almost any program with a smaller javascript version, if I put in "enough effort". It's not a reasonable way to compare anything.
You should actually try that, and compare sizes with the asm hello world.
Hello world in C becomes anywhere from 120KB to 1.2MB even if just using puts. Even setting the entry point to a function with no arguments doesn't help.
A tiny hello world ends up needing to ignore the standard library and use a console output function from the OS.
If you go to an embedded point of view where there is nothing already supplied, you can get a hello world, even with a basic printf, down to that size.
It is an order of magnitude bigger than the assembly version.
It prints (via write syscall) "hello world.\n" and then calls exit(0).
Assembled with fasm, linked with ld -n, then stripped.
The difference is between just using asm, or going out of the way to try to coerce a C toolchain to minimize the bloat.
When I tell it to emit the assembly with "-S" I get 28 lines of code when I have a feeling assembly is much shorter.