5 ms·
When I see FORTH stuff like this, I cannot avoid thinking that in a post apocalyptic world, we would be scavenging computer parts and writing FORTHs to use them
by haolez 4y ago
When I see FORTH stuff like this, I cannot avoid thinking that in a post apocalyptic world, we would be scavenging computer parts and writing FORTHs to use them :)
- stevekemp 4y agoOn that theme, collapse-OS has a discussion: http://collapseos.org/forth.html http://collapseos.org/forth.html
- WalterGR 4y ago“Forth isn't particularly fast either. As an interpreted language, it is blazing fast, but the speed tax of the threaded model still has to be paid, so it will generally be slower than code produced by a C compiler.” Not being familiar with this sense of “thread,” I found a good explainer here: https://www.complang.tuwien.ac.at/forth/threaded-code.html https://www.complang.tuwien.ac.at/forth/threaded-code.html And, as always, Wikipedia: https://en.m.wikipedia.org/wiki/Threaded_code https://en.m.wikipedia.org/wiki/Threaded_code
- rwmj 4y agoThere are a few issues here. Running threaded code interacts badly with branch prediction. Essentially every "word" (operation) is followed by a branch to the next word, and those seem hard to predict (or at least with 2010-era hardware they were very hard to predict, maybe more modern branch prediction can do better?). The reason is that a popular word, say, +/add, might be called from all over the program. Only one copy of the word exists and the indirect jump to the next word could go anywhere. However Forth does allow you to "inline" words, basically form a new word by chaining together existing words, which avoids this overhead. This doesn't optimise adjacent words, but it still gets semi-reasonable performance. (Inlining in JONESFORTH: https://github.com/nornagon/jonesforth/blob/d97a25bb0b06fb58da1975eac291f45618fd2ada/jonesforth.f#L1690 https://github.com/nornagon/jonesforth/blob/d97a25bb0b06fb58...) Modern Forths just have regular optimising compilers so none of this stuff applies, but they don't have the simple purity of one that you write and fully understand yourself.
- cmrdporcupine 4y agoIt's amazing to me in general how much of a divergence in expectations of performance vs reality that branch prediction misses causes in modern software. So many techniques that would improve performance on a 1980s processor can be woefully inefficient on a 21st century one. It's so easy to be still holding the computing model of the former in your head.
- kaba0 4y agoWhat is absolutely crazy is that many “primitive computation” is basically free. Like, there is more than likely some memory stalls either way and they just happen in the pauses not causing longer execution time.
- cmrdporcupine 4y agoI learned it the hard way when I was writing an emulator for a retro machine. Say you're blitting sprites to the screen. As you're drawing a line, each pixel either has some portion of a sprite, or doesn't. Your instinct is to do just like the hardware and 'chase the beam' and check at each pixel, or even just for each line, whether a sprite is present. Super wrong. You're far better off precomputing the whole sprite bitmap -- even if you don't end up using it and doing a bulk operation to display it or not display it. Because doing that "if sprite is here?" in a loop is super super expensive, more expensive than just blitting the splits and not using them. Most efficient ended up being precomputing things into boolean bitset vectors and using SIMD operations to do things based on those. Even if not doing GPU stuff, the fastest way to compute these days is to think of everything in bulk bulk bulk. The hardware we have now is super efficient at vector and matrix operations, so try to take advantage of it. (After doing this I have a hunch that a lot of the classic machine emulators <VICE, etc.> that are out there could be made way faster if they were rewritten in this way. )
- kaba0 4y agoJust an anecdotal experience, but I’m currently writing a JVM in Rust with a naive, interpreter loop. OpenJDK’s interpreter is a so-called template interpreter which looks at the method’s byte code and generates a given machine code snippet for each instruction, puts them serially next to each other and executes this buffer. The advantage of the latter is that in the interpreter loop model, one jumps back to the switch statement which will jump to the next instruction’s implementation, etc, while OpenJDK’s solution just continues execution serially, taking advantage of the branch predictor. In my benchmarks that are definitely not suitable to infer much, OpenJDK without JIT can perform 1.5-8x better, though of course the whole implementation is different so don’t read too much into that.
- shadowofneptune 4y agoTheaded code always interests me, but there definitely is a price to it. Should be noted though that a lot of newer Forths diverge from the classic threaded code model. Because it is a concatenative language, it is possible to have one that compiles native code by copying inlined subroutines (https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.56.1353&rep=rep1&type=pdf https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.56...). For example to compile : SQUARE DUP + ; all the compiler has to do is copy the machine code of DUP to the place where SQUARE is being compiled, remove the ret instruction at the end of it, and copy the machine code of + after it. It can also do some small optimizations to remove redundant instructions. You can do this with other languages, but concatenative languages can make it as simple as literally concatenating bits of code.
- kragen 4y agoYeah, that's pretty much how Ur-Scheme compiles, inspired by bigForth: http://canonical.org/~kragen/sw/urscheme http://canonical.org/~kragen/sw/urscheme
- j6a 4y agokragen, I emailed you on the 28th, can you please check it?
- kragen 4y agoNot finding anything with from-address containing "j6a". Sorry, I'm not doing very well, so I apologize if I should recognize you.
- j6a 4y agono reason you'd recognize this account that i just made, but I just resent the email and added j6a to the subject, so can you please check again.
- j6a 4y agohere's a hint: you sent me this link a while ago. also, i sent you something and am trying to make sure you get it. https://news.ycombinator.com/item?id=28936057 https://news.ycombinator.com/item?id=28936057
- retrac 4y agoAs with all languages, the compiled/interpreted distinction is a thing of convention/existing tools. Interpreted Forth is small, and tolerable speed-wise for tiny systems. But Forth can also be compiled directly to native machine code. Relatively easily, you can get rid of the interpreter overhead by writing blocks of machine code that do each Forth word's action, instead of bytecode to dispatch the interpreter to each of those routines. Forth can be adapted for that easily enough, and some Forths do support this on a per-word basis, allowing you to pick how you want your words compiled. Forth can also get the whole optimizing compiler treatment. Some optimizing Forth compilers have been released, but I don't know how good they were/are. Certainly never needed that kind of speed myself. I don't know if any Forth yet benefited from it, but a lot of work was put into Java, on approaches for optimizing stack machine-style code to reasonably fast native code for register machines.
- carapace 4y agoI just used Jonesforth as a guide/model to write a Forth for the Project Oberon RISC chip last week. It's not finished yet but it works: https://git.sr.ht/~sforman/PythonOberon/tree/master/item/forth/oberonforth.py https://git.sr.ht/~sforman/PythonOberon/tree/master/item/for... https://git.sr.ht/~sforman/PythonOberon/tree/master/item/forth/oberonforth.oberonforth https://git.sr.ht/~sforman/PythonOberon/tree/master/item/for... The idea is to make something like (or a port of) CollapseOS, but with a 32-bit machine. The Oberon RISC chip is big enough to be more useful than 8-bit systems yet simple enough that you could build one out of discreet components if you had to. It's really really simple.
- 7373737373 4y agoSee https://bootstrapping.miraheze.org/wiki/Main_Page https://bootstrapping.miraheze.org/wiki/Main_Page > This wiki is about bootstrapping, i.e., building up compilers and interpreters and tools from nothing.
- mncharity 4y agoFor a different apocalypse poem, allow everything existing to be used, but the coming population collapse demands a full stack replacement. To preserve existing capabilities and progress, but supported by far fewer people. We've had environments with far greater individual programmer productivity than is currently common. But while forth starts out nicely with simple systems, costs escalate unhappily with goal complexity. Similarly with smalltalk, lispms, prolog, haskell. The perennial "we'll easily do a full-stack rewrite in our wonderful X" efforts... haven't. Past/current efforts avoid implausible goals, like LLVM-quality compilation has to become a one-person project. Or slather on viability constraints, like must run on M in time T, and be accessible to population P. Or "we don't know how to compile that leverage efficiently and consistently - that paper hasn't been written yet - so you can't have it". But there are increasingly opportunities to do things differently now, if narrower goals demanded it. Community-wide compilation caches - "it ok that the type proof / bulk code translation / whatever sometimes takes days, it only needs to happen once". Compiler runs spinning up 10000 cloud instances. And so on. What might it look like, to attempt not merely a bootstrap, but a subsuming breakaway?
- eternityforest 4y agoI think the current system would be supportable with a collapse. You have fewer developers... but also fewer hackers, so I would guess security stays the same, other than if the collapse created extra crime incentive. We could just freeze all the fundamentals. If it was a real emergency, we could mostly stop working on new niche languages,Stop adding language features, stop deprecating stuff, and just focus on essential applications with only the tech we have. We'd obviously want some level or new work on the fundamentals and language level stuff, but we'd just focus on things that help you code with less people and poorly trained people(Replacing C with Rust could be the big project of the century). Tech is pretty great at the moment, seems like we could just get by for centuries, totally long enough to rebuild, if we just had what we have now, and enough hardware infrastructure to keep the fabs running. We don't really need a new kernel or a new graphics card architecture until society is stable again.
- mncharity 4y ago
- astrobe_ 4y agoWhen I see "Forth" weirdly capitalized like that, I remember that it is also an English word.