4 ms·
The assembly version looks simpler and more maintainable than any of the C versions. What's the overhead of using it? Having to rewrite for each architecture yo
by jl6 13y ago
The assembly version looks simpler and more maintainable than any of the C versions. What's the overhead of using it? Having to rewrite for each architecture you target (likely to be only 2 or 3)? If this level of optimisation matters to you then I guess you'd be down in assembly anyway?
- simias 13y agoIt's always better to have a single C code for all architectures than an assembly stub for each, it reduces the chance to have different behaviours across implementations (or subtle bugs in one implementation but not the other). Don't let the small clean assembly for this simple function fool you, writing optimized assembly on modern architectures is getting harder and harder, you have to take the cache into account for instance (both instruction and data) as well the particular implementation of the instruction on the CPU (microcode etc...). Fewer instructions does not always mean faster code, maybe TFA should have been more explicit about that instead of just saying it's "a crude measure of code quality". Look at the assembly generated by a compiler for a modern X86-64 architecture, you will see stuff that seem to make no sense such as NOPs in the middle of functions. Also, in general, it's interesting to know what the compiler can and cannot optimize to decide when it's interesting to handcraft some assembly. It's always better to benchmark first instead of doing some premature optimization. For instance, C does not have a bitwise rotation operator (while many architectures support a rotate instruction) but gcc easily recognizes rotation patterns and optimizes them without trouble.
- ANTSANTS 13y ago>It's always better to have a single C code for all architectures than an assembly stub for each, it reduces the chance to have different behaviours across implementations (or subtle bugs in one implementation but not the other). >Don't let the small clean assembly for this simple function fool you, writing optimized assembly on modern architectures is getting harder and harder Maybe in the general case, but this is literally a single instruction over unchecked arithmetic. You just add and then branch on overflow. Kinda hard to screw that up. It's really sad that people are so afraid of assembly these days that they can't even bother to write, say, a couple lines of assembly for their language VM's overflow-checking add instruction, and rely on hacks like this instead. Who cares if pure C is more portable if the assembly is shorter and it takes two minutes at worst to look up what the opcode for "branch on overflow" is for any other platform you want to port to? At some point, you're not playing it safe or even saving much time, you're just wasting CPU for the sake of laziness.
- pm215 13y agoThe project I work on compiles for eight different target architectures. Debian supports at least fourteen. Every program in a Linux distribution which has any inline assembly code means extra work that has to be done to support porting that distro to a new architecture, and code that has to be audited if an existing architecture gets a new calling convention (like x86's "x32", or ARM "hardfloat"). A portable 10-line implementation that gets reviewed and tested once is often going to be better than half a dozen 5 line architecture specific implementations.
- simias 13y agoYou'll probably still have to write the C version anyway, as a fallback if you build on a new architecture and as a reference implementation to test the asm. So at that point it's probably valuable to see if you can't get the compiler to generate the correct code by itself in a portable way. I'm not afraid of writing assembly when I have to but I always consider it a last resort scenario when I really can't get the same result with some good old C.
- cokernel_hacker 13y agoEven if you could write perfect assembly, sticking it in your program makes it more difficult for optimizations to flow across the assembly you have written because it is opaque to the compiler. Better yet, imagine that the compiler has performed value range propagation [1] to determine that the range checks, after inlining, were redundant or simply elidable. This would be infeasible if it were written in assembly. [1] http://llvm.org/devmtg/2007-05/05-Lewycky-Predsimplify.pdf http://llvm.org/devmtg/2007-05/05-Lewycky-Predsimplify.pdf
- userbinator 13y agoIf compilers don't understand inline Asm, maybe instead of avoiding it, why not try improving the compiler so it can understand? I know this can't be done if e.g. you use newer instructions that it doesn't know about and wouldn't emit anyway, but in the case of faster, shorter sequences using existing instructions and having an equivalent in C, I don't see why it can't "decompile" the instructions you write and use that information for optimisation. Even better if the compiler can learn from it and use that faster/shorter instruction sequence when it sees that expression in the future. Better yet, imagine that the compiler has performed value range propagation [...] This would be infeasible if it were written in assembly. VRP doesn't depend on the instruction set; it could be LLVM IR or it could be x86 or ARM or 6502 or anything else. It's just looking at values and operations on them.
- ksk 13y agoHuh? ... decompile the optimized instructions to what? There is no "equivalent C". That's the entire point. Otherwise someone would just write it in C and the codegen would emit the optimized instructions.
- erichocean 13y ago> Huh? ... decompile the optimized instructions to what? To the compiler's own IR, whatever that is.
- caf 13y ago