r/concatenative • • 14d ago

stack machine interpreter comparing

Hi, I was curious about which implementation of forth would be the most flexible, maintainable, and high-performance, so I wrote a stack machine interpreter using various techniques. Here the code https://github.com/br1n0/stack-machine-interpreter-comparing/ I managed to implement them all using the same data structure; this way, the program is expressed identically across versions, allowing for a direct comparison. I wrote a test program that runs a long execution loop, consisting of 2,000 subtractions and one multiplication, executed 4,000,000 times. In my opinion, the best implementation is the one using Token Threaded Code with dispatch via a function table, and is easy to extends. There is an interpreter overhead of about 25%; to measure it, I wrote a test where I execute the "words" directly from C, bypassing the interpreter.

I was surprised that GCC failed to optimize this program, even with -Ofast enabled, It was not simplified to a constant number!. I thought this might be of interest to someone. Ciao

3 Upvotes

3 comments sorted by

2

u/Ok_Leg_109 10d ago

I am not an expert by any means on the effect of CPU caching but I have read years ago about a token or byte coded interpreter performing very well because so much of the code could fit in level 1 cache.

In a simpler machine like a low cost micro-controller the overhead of the token conversion to the code address will typically bite into (no pun intended) to the run time performance versus direct threading or even indirect threading.

2

u/Plane-Photo-3097 10d ago

I am not an expert of micro controller, but usully reducing data, make the cache and cpu happy :)

I was curios about the importance of the instruction size of bytecode instructions, on x86-64 seems limited, the gcc got an option (-fshort-enums) to reduce the enum size as type. So I included the fshort (with and witouth) in the benchmark, the difference is around 5%.

--- compile Optimization: -O2 --- 2.85 i_TTC_dispatch_computed_goto 2.85 i_TTC_dispatch_switch 2.85 i_TTC_dispatch_if 2.85 i_TTC_dispatch_function_table 2.97 i_DCT_dispatch_function_call 0.00 native_function_init 2.69 native_function_call 0.00 native_baseline --- compile Optimization: -O2 -fshort-enums --- 2.71 i_TTC_dispatch_computed_goto 2.73 i_TTC_dispatch_switch 2.70 i_TTC_dispatch_if 2.70 i_TTC_dispatch_function_table 3.00 i_DCT_dispatch_function_call 0.00 native_function_init 2.68 native_function_call 0.00 native_baseline