[Vm-dev] Direct object pointers vs indirect ones pros and cons
Igor Stasenko
siguctua at gmail.com
Sat Nov 13 02:17:02 UTC 2010
On 12 November 2010 17:44, Bert Freudenberg <bert at freudenbergs.de> wrote:
>
> On 12.11.2010, at 14:41, Igor Stasenko wrote:
>
>> I'm inviting you to make own version of benchmark
>
> I don't think this can be realistically simulated inside Squeak. But possibly you could change the macros in sqMemoryAccess.h to fake an object table access?
>
> I just tried that. Using tinyBenchmarks, byte code performance drops to 63% and sends to 78%.
>
> Now declaring that variable volatile might be overkill as it prevents all caching, but I couldn't quite figure out a more realistic declaration.
>
you mean that non-volatile like:
int FakeObjTable = 0;
could be optimized away by compiler?
Well, since compiler compiles module by module (a separate C files),
if you remove 'static'
it can no longer able to optimize it to no-op, since it can't guess
what may happen to this variable in another object file,
since even if in one module there only a read-only access to it, some
other module could contain a code which modifying it.
So, i think this is the worst case performance slowdown. :)
If we take into account that to get object location you need to do
object table look only once,
and then any consequent read/write operations on object won't require
table lookup, this can be improved.
Consider, for example, that to read ivar, interpreter reads & checks
header, and only then ivar slot, so it should cost:
1 table lookup and 2 reads at object location.
instead of 2 table lookups + 2 reads at object location.
> - Bert -
>
> #else
> # ifndef FAKE_OBJ_TABLE
> # define FAKE_OBJ_TABLE
> static volatile int FakeObjTable= 0;
> # define OBJTABLELOOKUP(oop) (oop + FakeObjTable)
> # endif
> /* Use macros when static inline functions aren't efficient. */
> # define byteAtPointer(ptr) ((sqInt)(*((unsigned char *)(OBJTABLELOOKUP(ptr)))))
> # define byteAtPointerput(ptr, val) ((sqInt)(*((unsigned char *)(OBJTABLELOOKUP(ptr)))= (unsigned char)(val)))
> # define shortAtPointer(ptr) ((sqInt)(*((short *)(OBJTABLELOOKUP(ptr)))))
> # define shortAtPointerput(ptr, val) ((sqInt)(*((short *)(OBJTABLELOOKUP(ptr)))= (short)(val)))
> # define intAtPointer(ptr) ((sqInt)(*((unsigned int *)(OBJTABLELOOKUP(ptr)))))
> # define intAtPointerput(ptr, val) ((sqInt)(*((unsigned int *)(OBJTABLELOOKUP(ptr)))= (int)(val)))
> # define longAtPointer(ptr) ((sqInt)(*((sqInt *)(OBJTABLELOOKUP(ptr)))))
> # define longAtPointerput(ptr, val) ((sqInt)(*((sqInt *)(OBJTABLELOOKUP(ptr)))= (sqInt)(val)))
> # define oopAtPointer(ptr) (sqInt)(*((sqInt *)OBJTABLELOOKUP(ptr)))
> # define oopAtPointerput(ptr, val) (sqInt)(*((sqInt *)OBJTABLELOOKUP(ptr))= (sqInt)val)
> # define pointerForOop(oop) ((char *)(sqMemoryBase + ((usqInt)(oop))))
> # define oopForPointer(ptr) ((sqInt)(((char *)(ptr)) - (sqMemoryBase)))
> # define byteAt(oop) byteAtPointer(pointerForOop(oop))
> # define byteAtput(oop, val) byteAtPointerput(pointerForOop(oop), (val))
> # define shortAt(oop) shortAtPointer(pointerForOop(oop))
> # define shortAtput(oop, val) shortAtPointerput(pointerForOop(oop), (val))
> # define longAt(oop) longAtPointer(pointerForOop(oop))
> # define longAtput(oop, val) longAtPointerput(pointerForOop(oop), (val))
> # define intAt(oop) intAtPointer(pointerForOop(oop))
> # define intAtput(oop, val) intAtPointerput(pointerForOop(oop), (val))
> # define oopAt(oop) oopAtPointer(pointerForOop(oop))
> # define oopAtput(oop, val) oopAtPointerput(pointerForOop(oop), (val))
> #endif
>
>
--
Best regards,
Igor Stasenko AKA sig.
More information about the Vm-dev
mailing list