Quick sketch for Cogit augmentation of plugin primitives

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Quick sketch for Cogit augmentation of plugin primitives

Eliot Miranda-2
 
Hi All,

    just a quick sketch of an idea (and a bucket of whitewash) in the light of finding that 

FloatArray>>at: index
<primitive: 'primitiveAt' module: 'FloatArrayPlugin'>
^Float fromIEEE32Bit: (self basicAt: index)

and at:put: are very slow.  The basic idea is to annotate selected internal plugin primitive implementation methods with a corresponding Cogit or CogObjectRepresentation generator for a machine code version of the primitive.  FloatArray>>at:put: is I think about 6 times slower than the native Cogit implementation of at:put:; this because invoking plugin primitives is very slow (native stack pointers must be written back to the interpreter's stack pointers, arguments must be pushed onto the stack, the primFailCode must be tested explicitly).

First, Roni has added some single-precision float support to the Cogit for Lowcode.  To do single-precision to double-precision we would still need something like ConvertRsRd and ConvertRdRs to do the conversion.  A related task is to implement the Lowcode instruction support for the other platforms; Roni has done x86 (IA32), which leaves ARMv6 & 7, x86-64 and MIPS32.

Second, one could add a translation-time scheme to associate specific plugin primitives with JIT versions.  For example, let's imagine we annotate the above's corresponding primitive implementation as:

FloatArrayPlugin>>primitiveAt
<cogitPrimitive: #genFloatArrayPluginAt>
| index rcvr floatValue floatPtr |
<export: true>
<var: #floatValue type: #double>
<var: #floatPtr type: #'float *'>
index := interpreterProxy stackIntegerValue: 0.
rcvr := interpreterProxy stackValue: 1.
(interpreterProxy failed not
and: [(interpreterProxy isWords: rcvr)
and: [index > 0 and: [index <= (interpreterProxy slotSizeOf: rcvr)]]]) ifFalse:
[^interpreterProxy primitiveFail].
floatPtr := interpreterProxy firstIndexableField: rcvr.
floatValue := (floatPtr at: index-1) asFloat.
interpreterProxy pop: 2.
interpreterProxy pushFloat: floatValue

and then generate a string table that contains the tuple {"FloatArrayPlugin", "primitiveAt", genFloatArrayPluginAt } which could be consulted by the Cogit whenever a plugin primitive call in an internal plugin occurs in a jitter method.  The Cogit would then generate the call via the generator, which might or might not fall back on the plugin primitive in unusual circumstances, but would handle the common case in machine code and reap much improved performance as a result.

Don't have time to do this now (perhaps you do ;-) ) so documenting the idea to not forget it.


Candidates: FloatArrayPlugin at: at:put:, LargeIntegerArithmeticPlugin comparisons.
_,,,^..^,,,_
best, Eliot