On 12 November 2010 17:44, Bert Freudenberg bert@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