On Tue, Dec 1, 2009 at 11:38 PM, Ian Lance Taylor <
ia...@google.com> wrote:
> Mat <
dam...@web.de> writes:
>> I want to port a stack based vm from C which cache TOS in a register
>> and uses replicating-switch threading to grain performance. In C I can
>> simply create a preprocessor macro for the switch construct; It looks
>> like this:
>>
>> switch (VmAdrSpace[VmPC++])
>> {
>> case VmADD: VmTOS = VmTOS + VmDS[VmDSP++]; switch (VmAdrSpace[VmPC+
>> +]) ....
>>
>> This behavior is important for the runtime performance because a
>> single switch construct not only adds run-time checks for every
>> iteration but should compile at best to a jump table which share it's
>> jump address. This generates on almost modern CPU's a high rate of BTB
>> mis-predictions resulting in a really bad run-time performance.
>> Replicating-switch threading fix this though replicating of the switch
>> construct.
>>
>> Can I express this technique in GO without using something like Perl
>> (I found even False more intuitive) for preprocessing ?
>
> I'm not certain, but I expect that the answer here is no.
GCC supports a related C language extension: labels as values
(
http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Labels-as-Values.html).
It makes labels values and extends the goto statement to support
computed jumps:
static void *array[] = { &&foo, &&bar, &&hack };
goto *array[i];
In Go you could put each opcode implementation into its own function
and keep an array of function pointers. At the end of each operation,
instead of returning, you perform a tail-call to the next opcode via
the array of function pointers. This requires tail-call optimization
and function calls to be cheap. I haven't looked at the gc or gccgo
output for this, but it's probably faster to use a loop with a single
switch statement inside it.
Since Go supports labels, it may be possible to get the equivalent of
GCC labels as values in Go with some compiler changes?
Stefan