
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/