3 ms·
Interesting...some things to consider when building a VM (not this particular one, but in general -- and I am by no means an expert, and could be wrong on some
by gavanwoolery 15y ago
Interesting...some things to consider when building a VM (not this particular one, but in general -- and I am by no means an expert, and could be wrong on some of these things, although I have built my own compiler and VM from the ground up):
If possible, avoid shorts, bytes, and compressed byte code. Most CPUs work with 32 and 64 bit numbers, and they will convert bytes/shorts to 32 bits usually, which takes time (your compiler may do this regardless, depending on optimization, but anyhow it keeps your VM smaller and cleaner). Also, your VM would need to support every permutation of action (add a byte to an int, a int to a short, etc). Also, compressing an instruction into a 32 bit or 64 bit space is adverse to performance. Memory is plentiful enough (both RAM and cache) that you should not bother with this unless you are targeting an embedded device or something.
Use enums for your op codes, and a switch statement (depends on compiler). If you use enums and a switch, the compiler can generate a jump table because it knows the enum will always be in a certain range. Much better performance than a bunch of if/else statements.
It is possible to write a VM that only uses floating point numbers, if you want to keep the VM as small and simple as possible. This means casting the floats for things like addressing, but otherwise I think it might perform well.
- Chirono 15y agoUse enums for your op codes, and a switch statement (depends on compiler). If you use enums and a switch, the compiler can generate a jump table because it knows the enum will always be in a certain range. Much better performance than a bunch of if/else statements. You can generate some beautifully simple interpreters this way, but switch/dispatch is not the way to go for high performance. Jump tables like that are not a good candidate for optimisation by compilers and they kill any sort of branch prediction your CPU is doing. Here's an post (and follow up discussion) by the author of the Lua, where he explains why the main loop is written in assembler and why it beats compilers: http://news.ycombinator.com/item?id=2588696 http://news.ycombinator.com/item?id=2588696