On Fri, Jul 23, 2010 at 1:18 AM, Stefan Behnel <[email protected]> wrote: > Robert Bradshaw, 23.07.2010 08:52: >> On Thu, Jul 22, 2010 at 11:10 PM, Stefan Behnel wrote: >>> Stefan Brunthaler started a thread on python-dev about a couple of patches >>> he has written for CPython as part of his PhD. It seems that he has >>> implemented inline caching for CPython. >>> >>> http://comments.gmane.org/gmane.comp.python.devel/115362 >>> >>> http://en.wikipedia.org/wiki/Inline_caching >>> >>> Something like this might be interesting for Cython, too. He hasn't >>> published the patches yet, but they might well be worth a look when he does. >> >> Very cool. I have actually thought a lot about this, and I know >> unladen swallow did some stuff in this direction for module/builtin >> lookups. Ideally, there could be some kind of a hook called, or even a >> dirty bit, that gets set when an objects attribute set gets modified, >> so we wouldn't have to re-look things up most of the time. > > I just had a funny idea. We could simply embed each call to a Python method > in a snippet of code that does a bit of caching. It would use a fixed size > static C array (say, size 4) of structs for each call node: > > {Python type, underlying C function of method} > > and add all types to that array that it finds as call target at runtime > that do not have a __dict__ (most builtin types but (sadly) no modules). > Then, before doing the CPython call dance, it would just quickly run > through the array to check if it finds the current type, and on success, > call the function for that method directly. The normal Python attribute > lookup and call would then become a fallback that would only be required > for dynamic Python objects. We could also add types to it that we deem > unoptimisable (e.g. because the method is not efficiently callable) and set > their method pointer to NULL, so that we can skip over any further > optimisation attempts in the future. We always hold the GIL when > manipulating the arrays, so static caching will work perfectly. > > What do you think?
There is a nontrivial amount of boilerplate that the CPython CallObject methods do w.r.t. dispatching to different kinds of methods, so we may want to, e.g. specialize to methods that have a single calling convention (that matches the way they are used?) I think the real savings is in larger class hierarchies, and there we really need some CPython hook to verify that the dictionaries have not changed. > I'm not so sure yet about the ref-counting implications of keeping such a > static pointer to a type, that may also need some more consideration. A > borrowed reference will not work if the type is allowed to get garbage > collected, as the type's address may then end up being reused for another > type, leaving the method pointer invalid. That could be an issue, as types can get garbage collected. - Robert _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
