Live data from Hacker News

Floppy Bird: A Flappy Bird clone in 16-bit x86 assembly

github.com

71–73 of 73 posts

Re: Floppy Bird: A Flappy Bird clone in 16-bit x86 assembly

#71

Earlier quoted context omitted.

> Hardware access (not exposed by other languages), speed, and possibly executable size are the practical reasons one would write in assembly. This is a bit misleading, accesses to physical memory, disks and to other devices are usually protected by the operating system, not by the language. So you don't have direct hardware access because you program in assembly, but because you run a program without the control of…

>The only thing that you can do with assembly and that you can't really do with higher level language like C is accessing processor specific registers/instruction sets (e.g. SSE). And this is typically done using inline assembly snippets, as there is no reason to write a whole program in assembly when you only need to optimize a single function. The other three most important things you can do in assembly that you ca…

'It can absolutely be worthwhile to write an appreciable portion of a program in assembly if these "features" make the code significantly faster or even easier to express.'

Strictly speaking, yes. I would urge some hesitancy in concluding that is the case, though.

WRT the first, you take some portability penalty for using GNU extensions, but that is probably significantly less than you take by writing in assembly. Unless you're targeting an architecture GCC does not target and your alternative compilers don't have a similar extension, you should still not be writing assembly for this reason alone.

"Directly accessing status flags like the carry flag (necessary for efficiently implementing bignum arithmetic and CPU emulators)"

This falls under both "hardware access" and speed. It certainly is a reason to occasionally break out the inline assembly.

"and optimizing register allocation across complicated control flow (like language interpreters or emulators)"

This is a very bad reason until it actually proves strictly necessary (at which point it falls back under speed and/or size). Modern compilers are quite good at register allocation and getting better, and chip architectures are complicated enough that you're likely to be wrong about what's fastest and/or best. The ability to rapidly try new things will probably get you faster results faster - compare the time taken tweaking optimization flags and rebuilding, versus working out an alternative register allocation and threading it through all the relevant code. Moreover, a small change in requirements can entirely invalidate all of that work. An understanding of assembly and your target architecture sufficient to allow you to allocate registers by hand is still highly valuable when you get into that space, though, so you understand what you're looking for when comparing generated code and benchmark results.

Re: Floppy Bird: A Flappy Bird clone in 16-bit x86 assembly

#72

Earlier quoted context omitted.

>The only thing that you can do with assembly and that you can't really do with higher level language like C is accessing processor specific registers/instruction sets (e.g. SSE). And this is typically done using inline assembly snippets, as there is no reason to write a whole program in assembly when you only need to optimize a single function. The other three most important things you can do in assembly that you ca…

'It can absolutely be worthwhile to write an appreciable portion of a program in assembly if these "features" make the code significantly faster or even easier to express.' Strictly speaking, yes. I would urge some hesitancy in concluding that is the case, though. WRT the first, you take some portability penalty for using GNU extensions, but that is probably significantly less than you take by writing in assembly. Un…

>This falls under both "hardware access"

I don't really agree with that, unless you want to call any use of a CPU "hardware access," but ok. I also don't consider it to be like accessing architecture specific instructions like SSE, because I simply cannot think of a general purpose CPU from the dawn of the micro that lacks the basic carry, overflow, zero, and sign flags, and the ability to branch on them.

>WRT the first, you take some portability penalty for using GNU extensions, but that is probably significantly less than you take by writing in assembly.

In practice, for a lot of developers, there are only one or two relevant CPU architectures, and they're almost always from the set of 32 and 64-bit x86 and ARM. Depending on what kind of program you're writing, it could be much more likely that you'd switch C or C++ compilers than switch target architectures. And if you are programming for obscure microcontrollers or whatever, you've pretty much thrown portability out of the roof to begin with and writing the whole program in assembly is not out of the question.

>Modern compilers are quite good at register allocation and getting better, and chip architectures are complicated enough that you're likely to be wrong about what's fastest and/or best.

Compilers are pretty bad at optimizing virtual machine interpreters, and this is unlikely to change. Here we go, straight from the horse's (or, uh, Mike Pall's) mouth:

http://article.gmane.org/gmane.comp.lang.lua.general/75426

http://www.reddit.com/r/programming/comments/badl2/luajit_2_...

http://www.reddit.com/r/programming/comments/hkzg8/author_of...

Re: Floppy Bird: A Flappy Bird clone in 16-bit x86 assembly

#73

Earlier quoted context omitted.

'It can absolutely be worthwhile to write an appreciable portion of a program in assembly if these "features" make the code significantly faster or even easier to express.' Strictly speaking, yes. I would urge some hesitancy in concluding that is the case, though. WRT the first, you take some portability penalty for using GNU extensions, but that is probably significantly less than you take by writing in assembly. Un…

>This falls under both "hardware access" I don't really agree with that, unless you want to call any use of a CPU "hardware access," but ok. I also don't consider it to be like accessing architecture specific instructions like SSE, because I simply cannot think of a general purpose CPU from the dawn of the micro that lacks the basic carry, overflow, zero, and sign flags, and the ability to branch on them. >WRT the fi…

"Compilers are pretty bad at optimizing virtual machine interpreters, and this is unlikely to change. Here we go, straight from the horse's (or, uh, Mike Pall's) mouth"

This could possibly fall into my "strictly necessary" bucket. I'm not sure what the timing differences actually amount to, either - I've got a threaded interpreter in a fast path in some of my code, and it hasn't proved a bottleneck (less than 1% of time during a low-latency event is spent running the programs) so I've not looked closely at register allocation through it.

I reiterate that this comes at severe cost to ease of extension and refactoring, however, and shouldn't be undertaken lightly.

Post reply on HN