| 
	
 | 
 Posted by Rasmus Lerdorf on 07/06/05 08:43 
Dan Rossi wrote: 
>  
> On 06/07/2005, at 5:05 AM, Jochem Maas wrote: 
>  
>>>> 
>> 
>> well I hadn't got a clue about this vm stuff but I read that 
>> there are CALL, GOTO and SWITCH [vm?] models implemented. according to 
>> 'Seb' CALL goes fastest. But I would assume that offering different vm 
>> models meant that raw speed is not the only factor (otherwise why not 
>> concentrate all efforts on just the CALL code) - could someone** give a 
>> hint (or a link :-) as to what the VMs mean for people who have the 
>> choice? 
>> (i.e. in full control of the server running their code) 
>> 
>> I could imagine that the different VMs are tuned to different styles of 
>> code (e.g. OO & procedural) or different tasks? (web, cmdline, deamon) 
>> ...is this anyway near the truth? 
>> 
>> 
>> 
>  
> Wow interesting, tuned for different tasks ey ? If i must of read wrong, 
> Seb's benches said GOTO was the better compile option ? I am still 
> curious what all 3 mean :D 
 
It depends a lot on the architecture, the compiler and the compiler 
settings you use.  In realworld use, the differences between them are minor. 
 
If you are interested in the technical difference, it lies deep in the 
guts of the executor.  In somewhat simplified terms, the executor takes 
the list of opcodes generated by the language parser and calls some 
handling code for each one.  How the executor turns this list of opcodes 
(just numbers) into the correct set of calls is what these 3 types 
define.  The GOTO mechanism uses a bit of a compiler trick known as 
"computed gotos" to try to make each one a very simple branch at the 
assembly level.  It looks like this in C: 
 
int main(void) { 
  static void *ptr[3]={&&foo, &&bar}; 
 
  goto *ptr[1]; 
 
  foo: 
  printf("foo\n"); 
  return 0; 
 
  bar: 
  printf("bar\n"); 
  return 0; 
} 
 
That is, we can dynamically create a list of labels and then use a GOTO 
to jump directly to one of these dynamic labels.  Not instead of jumping 
to ptr[1] as in the above example, imagine making that a variable, say 
the opcode number, and doing the goto directly to the code defined for 
each opcode.  That's the GOTO VM.  And it should theoretically be the 
fastest assuming the compiler does the right thing. 
 
The SWITCH vm was originally just a big switch(opcode) { case 1: ...; 
case 2: ...' } It's a bit different now, but you can think of it in 
those terms.  Decent compilers should theoretically be able to optimize 
a clean set of cases to something close to simple branches, just like 
the computed goto case, but it can be hit and miss.  With the computed 
goto way of doing it, we are trying to send a stronger hint to the compiler. 
 
And finally the CALL vm basically just uses a function pointer to call 
the handling code.  Think of it as something alone the lines of 
${"handler_$i"}(); in PHP terms.  That is, you would have handler_1(), 
handler_2(), handler_3() functions defined and you dynamically determine 
which one to call based on the opcode. 
 
But again, you really shouldn't need to worry about this.  A single 
extra disk-touching system call will wipe out any minor gain you would 
see from switching the vm. 
 
-Rasmus
 
  
Navigation:
[Reply to this message] 
 |