4 ms·
The article doesn’t mention performance. Because Forth programs basically chain subroutine calls together, it’s a safe bet it is bad on modern hardware with its
by Someone 1y ago
The article doesn’t mention performance. Because Forth programs basically chain subroutine calls together, it’s a safe bet it is bad on modern hardware with its multitude of caches.
That’s something you could prevent with an advanced compiler that inlines lots of code and carefully tries to put functions often called together in cache lines, but this code doesn’t do that, and if you did, why spend that effort on your compiler if a simple traditional language makes that inlining easier?
- astrobe_ 1y agoYes, I observe a 30-40x slowdown with that method on my interpreter. I was perfectly aware of the cost, Anton Ertl had shown in the 90ies that it wasn't the best on Pentium already [1]. The trick is that you can regain 100% the speed of C (or machine code) by native-coding the critical parts. It's pretty much the same cheating method as JIT or calling native code with an FFI, just manual. In this regard, a simple, naive subroutine threaded scheme makes it very trivial to do. Think Lua extensions but even more easy because you don't have dynamic types or GC memory. Seriously, when I look hear that language X is "easy to extend" and I look at it... No, it is not. I have come to the same conclusions as eForth "independently" (I have looked at many Forth systems before making my own, so there could be some influences), except I wasn't interested in compatibility with the standard, so I ditched the counted strings for C's ASCIIZ strings. This makes interfacing with C/C++ libraries as straightforward as you can get. I quite don't understand why eForth goes for C++; I do see its value to parse more complex languages but Forth? I also don't see the value of multithreading. Cooperative schemes usually work well enough and are easier to handle. If concurrency is needed, multiple programs with RPC, shared memory or pipelines are options usually available (some options are more portable than others, though). > So, the question is, how to encourage today's world of C programmers to take a look at Forth. This is a huge mistake. If you make a Forth for others instead of doing it for your own needs, you are doing it wrong. Doing it for yourself, and not being tied by backwards compatibility because you have published your Forth and you don't want to lose your audience, leads to vastly different answers. [1] http://www.complang.tuwien.ac.at/projects/forth.html http://www.complang.tuwien.ac.at/projects/forth.html
- _0ffh 1y agoNo. Chaining subroutine calls is an implementation detail that is not inherent in the language, even if it may be a popular option because it is easy to do. The usual implementation options are subroutine threading, indirect threading, and direct threading.
- nickcw 1y agoI wrote a FORTH for ARM which inlined short definitions (eg stack manipulation) then did peephole optimization keeping the stack in registers for that word. The compiled code came out looking quite nice. I'm sure a decent C compiler would have done better, but it wasn't bad at all. It meant all the stack noise was compiled as register move instructions leaving only calls to chunky words which were too big to inline.
- anthk 1y agoThreaded Forth's date back to the 80's; they almost invented 'modern' task switching. Also: https://www.bradrodriguez.com/papers/mtasking.html https://www.bradrodriguez.com/papers/mtasking.html
- thesz 1y agoIf you doing your own Forth CPU, make a barrel one [1] to hide any overhead. State of such individual CPU is small, you can easily have thousands of them. [1] https://en.wikipedia.org/wiki/Barrel_processor https://en.wikipedia.org/wiki/Barrel_processor If you do your implementation on regular CPU, do a software pipelined [2] interpreter, which also can do several threads of execution simultaneously. [2] https://en.wikipedia.org/wiki/Software_pipelining https://en.wikipedia.org/wiki/Software_pipelining Software pipelined stack machine interpreter was used to compress code for VLIW DSP.
- scatbot 1y agoAny Forth system at it's core is essentially a stack-based virtual machine with a reprogrammable high-level assembler and a REPL. Some Forths use direct or indirect threading, others are implemented as bytecode VMs, not unlike the JVM, high-performance JavaScript engines or the Erlang VM, but that's really just an implementation detail. People say that stack juggling is boring, but I actually find it to be a very natural way to think about computation. Forth's linear, concatenative style gives you SSA-like semantics for free, which makes it straightforward to lower into register-optimized bytecode or native code. And once you're there, dynamic recompilation at runtime can do the rest. A naive, threaded implementation of Forth might not be performance-friendly on modern hardware, but there's nothing that prevents it from being high-performance. It just depends on how much effort you're willing to put into the implementation.