[Python-Dev] Re: Bytecode idea
Damien Morton
newsgroups1@bitfurnace.com
Wed, 26 Feb 2003 02:14:19 -0500
> Christian Tismer wrote:
> So what I would like to try is to merge all opcodes
> which have exactly the same pattern into one case,
> which then does the common preparation stuff and
> postprocessing including error handling, but internally
> dispatches on the function to be called.
I tried this on the 2.3a2 source, modifying it to implement your idea.
This was implemented on top of the LOAD_FAST_n, etc, changes.
No luck - it makes the code slower by nearly 5%, decreasing a base 22300
PyStones to 21100 PyStones. That is, the idea of using function pointers. I
imagine that a case statement would be even slower.
I didnt implement the table of function pointers as one monolithic table, as
the unary and binary functions have different signatures.
static binaryfunc binop[] = {
PyNumber_Multiply,
PyNumber_TrueDivide,
PyNumber_TrueDivide,
PyNumber_FloorDivide,
PyNumber_Remainder,
PyNumber_Lshift,
PyNumber_Rshift,
PyNumber_And,
PyNumber_Xor,
PyNumber_Or,
PyNumber_InPlaceMultiply,
PyNumber_InPlaceTrueDivide,
PyNumber_InPlaceTrueDivide,
PyNumber_InPlaceFloorDivide,
PyNumber_InPlaceRemainder,
PyNumber_InPlaceLshift,
PyNumber_InPlaceRshift,
PyNumber_InPlaceAnd,
PyNumber_InPlaceXor,
PyNumber_InPlaceOr
};
switch (opcode) {
...
case BINARY_MULTIPLY:
case BINARY_DIVIDE:
case BINARY_TRUE_DIVIDE:
case BINARY_FLOOR_DIVIDE:
case BINARY_MODULO:
case BINARY_LSHIFT:
case BINARY_RSHIFT:
case BINARY_AND:
case BINARY_XOR:
case BINARY_OR:
case INPLACE_MULTIPLY:
case INPLACE_DIVIDE:
case INPLACE_TRUE_DIVIDE:
case INPLACE_FLOOR_DIVIDE:
case INPLACE_MODULO:
case INPLACE_LSHIFT:
case INPLACE_RSHIFT:
case INPLACE_AND:
case INPLACE_XOR:
case INPLACE_OR:
w = POP();
v = TOP();
x = binop[opcode-BINARY_MULTIPLY](v, w);
Py_DECREF(v);
Py_DECREF(w);
SET_TOP(x);
if (x != NULL) continue;
break;
...
"Christian Tismer" <tismer@tismer.com> wrote in message
news:3E5C3915.6070600@tismer.com...
> Christian Tismer wrote:
> [much about bytecode, folding, ...]
>
> Well, to stop myself blathering about bytecode and
> how to make it different, which I'm expected to do
> other things or at least sleep, I can't resist
> to throw this rigorous idea into py-dev, which
> struck me at 4:30 in the morning:
>
> WHat would happen if we re-structured the ceval
> loop this way:
> We look at every similar pattern and group together
> all the opcodes which have a similar pattern.
> By "pattern" I mean the surrounding calls of simple
> things like stack operations before and after, and
> error handling.
>
> So what I would like to try is to merge all opcodes
> which have exactly the same pattern into one case,
> which then does the common preparation stuff and
> postprocessing including error handling, but internally
> dispatches on the function to be called.
>
> No idea if it may be an improvement, but just let me throw
> it in.
> Example:
>
> case UNARY_POSITIVE:
> v = POP();
> x = PyNumber_Positive(v);
> Py_DECREF(v);
> PUSH(x);
> if (x != NULL) continue;
> break;
>
> case UNARY_NEGATIVE:
> v = POP();
> x = PyNumber_Negative(v);
> Py_DECREF(v);
> PUSH(x);
> if (x != NULL) continue;
> break;
> ...
> case UNARY_CONVERT:
> v = POP();
> x = PyObject_Repr(v);
> Py_DECREF(v);
> PUSH(x);
> if (x != NULL) continue;
> break;
>
> case UNARY_INVERT:
> v = POP();
> x = PyNumber_Invert(v);
> Py_DECREF(v);
> PUSH(x);
> if (x != NULL) continue;
> break;
>
> is converted into
>
> case UNARY_POSITIVE:
> case UNARY_NEGATIVE:
> case UNARY_CONVERT:
> case UNARY_INVERT:
> v = POP();
> switch (opcode) {
> case UNARY_POSITIVE:
> x = PyNumber_Positive(v); break;
> case UNARY_NEGATIVE:
> x = PyNumber_Negative(v); break;
> case UNARY_CONVERT:
> x = PyObject_Repr(v); break;
> case UNARY_INVERT:
> x = PyNumber_Invert(v);
> }
> Py_DECREF(v);
> PUSH(x);
> if (x != NULL) continue;
> break;
>
> Maybe it also makes sense to use indexing into a static
> array, instead of the case construct. Note that there
> can be one single such table for all opcodes and all cases,
> since opcodes are still disjoint. It depends where this
> table is stored and if this can get in the cache.
>
> While I don't know if this really makes the interpreter
> more efficient, at least it makes it shorter to read
> and maybe easier to maintain.
>
> Ok ok, I will sleep now :-)
>
> cheers - chris
>
> --
> Christian Tismer :^) <mailto:tismer@tismer.com>
> Mission Impossible 5oftware : Have a break! Take a ride on Python's
> Johannes-Niemeyer-Weg 9a : *Starship* http://starship.python.net/
> 14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
> work +49 30 89 09 53 34 home +49 30 802 86 56 pager +49 173 24 18 776
> PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
> whom do you want to sponsor today? http://www.stackless.com/