🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Virtual Machine Switches

Started by
3 comments, last by shadowman13131 21 years ago
Hey, This isn't really a question, more of a thought. Most people that I've read their questions on how to do a virtual machine use a switch statement for the reason that it's simple and all of the functions of the language go in the same place. But then the issue of speed always pops up, once the language gets more than 10 instructions. Some people suggest virtual functions or a function table, which is a good idea. However, I would just like to put my two cents in saying why don't you just use what you've used to sort data to call the commands? I.E. Here is a normal virtual switch statement:

    switch (Cmd)
    {
    case 0: //do stuff

        break;
    case 1: //more...

        break;
    ...
    case 255: //last instruction...

        break;
    }

Correct? Now as you can guess if you're calling that 255th instruction it'll take awhile for the compiler to test to make sure the command is not all of the other commands. So why not break it into a hard-coded binary tree, or probably better just group the commands? I.E.:

//Binary tree

    if (Cmd < 128)
    {   
        if (Cmd < 64)
        {
            if (Cmd < 32)
            {  //ect down to....

             ...
                if (Cmd == 0)
                {
                    //do cmd 0

                }
                else
                {
                    //do cmd 1

                }

//or you could do it by grouping (it would be easier to add new commands)


    //first ten cmds

    if (Cmd < 10)
    {
        //switch statement/or more ifs to test the separate commands, or another group

    }
    else if (Cmd < 20)
    {
        //repeat

    }

See? Now from my observances that would be easier to read and much faster than just one long switch statement. The groups could even have subgroups, say you go in groups of commands 100, then inside the 100 you partition it into 10. With the binary tree the last command would take 7-8 tests rather than 255, and with the grouping it'd take (assuming you're blocking by 100's then 10's) 12 tests. The advantage to blocking would be that more used functions can easily be placed at the beginning of the block, and would require less tests. Tell me what you think. Walt Edit: Fixed source tags. [edited by - shadowman13131 on June 16, 2003 11:44:04 AM]
Advertisement
well, what i''m doing is grouping the opcodes by some sort of type, i.e. i have my integer instructions ranging from 32 to 64 (can''t remember excactly, just some numbers), and my floating-point instructions from 64 to 80 or whatever. this way the code is easy to read (at least it is for me) and easier to break up than a huge switch statement:

if ( op >= 32 && op <= 64 ){ //integer specific stuff   switch(op)   {   }}else if ( op >= 64 && op <= 80 ){ //floating point stuff}


in terms of speed i really don''t care how long it takes to lookup the right case in the switch(), i''m more concerned about the efficiency of the op''s themselves, like stack push/pop and memory accesses.

what i generally do in a switch statement is putting the cases which will probably called most right on top of the switch.
if you're using a char for the switch

char opcode=somecode;

swtich(opcode)


your compile will make a jumptable and not do 255 compares (i took a look at the disassembled code from my vc++ and I'm sure the gcc is doing the same)

greetz
rapso

[edited by - rapso on June 24, 2003 5:48:29 AM]
http://www.gamedev.net/community/forums/topic.asp?whichpage=3&pagesize=20&topic_id=162367

Please check out Page #2, it has the results of some benchmarks by me and another.
"premature optimization is evil" blah blah blah... why worry about a few cycles here and there when you don''t even know if it is a bottleneck yet?
--- krez ([email="krez_AT_optonline_DOT_net"]krez_AT_optonline_DOT_net[/email])

This topic is closed to new replies.

Advertisement