As per my comment on the recent Morphic performance graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59) on a Cog VM these primitives fail with a Float parameter, which leads to a huge performance hit when comparing Ints to Floats by doing silly things in the fallback code. Cog: [1 to: 2000000 do: [:i | i < 2354.234. i <= 2354.234. i >= 2354.234. i > 2354.234.]] timeToRun 26594 Trunk: [1 to: 2000000 do: [:i | i < 2354.234. i <= 2354.234. i >= 2354.234. i > 2354.234.]] timeToRun 229 Should this be changed in the VM, or is the difference for pure int/int comparition large enough that we should instead change Float>>adaptToInteger: andCompare: to use the corresponding comparitions with Float as receiver, which does work? That's still slower than trunk in my image, but quite a bit better, above test takes about 1s. Cheers, Henry |
Hmm.. that's really strange, because as far as i can see, the code there are the same: (primitive: 3) Interpreter>>primitiveLessThan | integerReceiver integerArgument | integerArgument := self popInteger. integerReceiver := self popInteger. self checkBooleanResult: integerReceiver < integerArgument InterpreterPrimitives>>primitiveLessThan | integerReceiver integerArgument | integerArgument := self popInteger. integerReceiver := self popInteger. self checkBooleanResult: integerReceiver < integerArgument and #popInteger also same (it fails if value on stack are not smallinteger). So, in Squeak VM comparison primitive also fails, which should lead to evaluating failure code. One way how to speed this up, is when primitive fails, do not use super-sends, but instead use double dispatch, i.e. instead : SmallInteger >> < aNumber "Primitive. Compare the receiver with the argument and answer with true if the receiver is less than the argument. Otherwise answer false. Fail if the argument is not a SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive." <primitive: 3> ^super < aNumber do something like: SmallInteger >> < aNumber "Primitive. Compare the receiver with the argument and answer with true if the receiver is less than the argument. Otherwise answer false. Fail if the argument is not a SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive." <primitive: 3> ^ aNumber isGreaterOrEqualToSmallInteger: self and then effectively, Float>> isGreaterOrEqualToSmallInteger: aSmallInteger could be implemented as a primitive which takes a smallinteger as argument and does comparison without need to convert integer to Float first. Also, a primitives for floats accepting a smallintegers as arguments, so by rewriting: SmallInteger >> < aNumber "Primitive. Compare the receiver with the argument and answer with true if the receiver is less than the argument. Otherwise answer false. Fail if the argument is not a SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive." <primitive: 3> ^ aNumber >= self [1 to: 2000000 do: [:i | i < 2354.234. ] timeToRun before: 8223 after: 20 so... 421 times faster :) On 2 May 2011 12:12, Henrik Sperre Johansen <[hidden email]> wrote: > > As per my comment on the recent Morphic performance > graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59) > on a Cog VM these primitives fail with a Float parameter, which leads to a > huge performance hit when comparing Ints to Floats by doing silly things in > the fallback code. > > Cog: > [1 to: 2000000 do: [:i | > i < 2354.234. > i <= 2354.234. > i >= 2354.234. > i > 2354.234.]] timeToRun 26594 > > Trunk: > [1 to: 2000000 do: [:i | > i < 2354.234. > i <= 2354.234. > i >= 2354.234. > i > 2354.234.]] timeToRun 229 > > Should this be changed in the VM, or is the difference for pure int/int > comparition large enough that we should instead change > Float>>adaptToInteger: andCompare: > to use the corresponding comparitions with Float as receiver, which does > work? > That's still slower than trunk in my image, but quite a bit better, above > test takes about 1s. > > Cheers, > Henry > -- Best regards, Igor Stasenko AKA sig. |
On 02.05.2011 12:48, Igor Stasenko wrote: > > Hmm.. that's really strange, because as far as i can see, > the code there are the same: > > (primitive: 3) > > Interpreter>>primitiveLessThan > | integerReceiver integerArgument | > integerArgument := self popInteger. > integerReceiver := self popInteger. > self checkBooleanResult: integerReceiver< integerArgument > > InterpreterPrimitives>>primitiveLessThan > | integerReceiver integerArgument | > integerArgument := self popInteger. > integerReceiver := self popInteger. > self checkBooleanResult: integerReceiver< integerArgument > > and #popInteger also same (it fails if value on stack are not smallinteger). > So, in Squeak VM comparison primitive also fails, > which should lead to evaluating failure code. genSmallIntegerComparison. > Also, a primitives for floats accepting a smallintegers as arguments, > so by rewriting: > > > SmallInteger>> < aNumber > "Primitive. Compare the receiver with the argument and answer with > true if the receiver is less than the argument. Otherwise answer false. > Fail if the argument is not a SmallInteger. Essential. No Lookup. See > Object documentation whatIsAPrimitive." > > <primitive: 3> > ^ aNumber>= self > > > [1 to: 2000000 do: [:i | > i< 2354.234. ] timeToRun > > before: > > 8223 > > after: > 20 > > so... 421 times faster :) different place. Cheers, Henry |
On 2 May 2011 13:06, Henrik Sperre Johansen <[hidden email]> wrote: > > On 02.05.2011 12:48, Igor Stasenko wrote: >> >> Hmm.. that's really strange, because as far as i can see, >> the code there are the same: >> >> (primitive: 3) >> >> Interpreter>>primitiveLessThan >> | integerReceiver integerArgument | >> integerArgument := self popInteger. >> integerReceiver := self popInteger. >> self checkBooleanResult: integerReceiver< integerArgument >> >> InterpreterPrimitives>>primitiveLessThan >> | integerReceiver integerArgument | >> integerArgument := self popInteger. >> integerReceiver := self popInteger. >> self checkBooleanResult: integerReceiver< integerArgument >> >> and #popInteger also same (it fails if value on stack are not >> smallinteger). >> So, in Squeak VM comparison primitive also fails, >> which should lead to evaluating failure code. > > Cog has translation methods for those primitives in cogit.c, see > genSmallIntegerComparison. > > >> Also, a primitives for floats accepting a smallintegers as arguments, >> so by rewriting: >> >> >> SmallInteger>> < aNumber >> "Primitive. Compare the receiver with the argument and answer with >> true if the receiver is less than the argument. Otherwise answer >> false. >> Fail if the argument is not a SmallInteger. Essential. No Lookup. >> See >> Object documentation whatIsAPrimitive." >> >> <primitive: 3> >> ^ aNumber>= self >> >> >> [1 to: 2000000 do: [:i | >> i< 2354.234. ] timeToRun >> >> before: >> >> 8223 >> >> after: >> 20 >> >> so... 421 times faster :) > > Yes, that's basically what I proposed to do in image, albeit in a different > place. > But i really wonder why it falls to normal send.. Consider this: StackInterpreter>>bytecodePrimLessThan | rcvr arg aBool | rcvr := self internalStackValue: 1. arg := self internalStackValue: 0. (self areIntegers: rcvr and: arg) ifTrue: ["The C code can avoid detagging since tagged integers are still signed. But this means the simulator must override to do detagging." ^self cCode: [self booleanCheat: rcvr < arg] inSmalltalk: [self booleanCheat: (objectMemory integerValueOf: rcvr) < (objectMemory integerValueOf: arg)]]. self initPrimCall. aBool := self primitiveFloatLess: rcvr thanArg: arg. self successful ifTrue: [^ self booleanCheat: aBool]. messageSelector := self specialSelector: 2. argumentCount := 1. self normalSend so, for #< send it tries to avoid doing normal send and instead tries to do quick int<int comparison first, and then float/int < float/int second (using #primitiveFloatLess:thanArg:) so it should not fall to normal send. So , i think the problem is, that #genSmallIntegerComparison: (and friends) generating code for comparing integers only and falls back to normal send when it fails, without attempting to use #primitiveFloatLess:thanArg: . > Cheers, > Henry > -- Best regards, Igor Stasenko AKA sig. |
On 02.05.2011 13:22, Igor Stasenko wrote: > > On 2 May 2011 13:06, Henrik Sperre Johansen > <[hidden email]> wrote: >> On 02.05.2011 12:48, Igor Stasenko wrote: >>> Hmm.. that's really strange, because as far as i can see, >>> the code there are the same: >>> >>> (primitive: 3) >>> >>> Interpreter>>primitiveLessThan >>> | integerReceiver integerArgument | >>> integerArgument := self popInteger. >>> integerReceiver := self popInteger. >>> self checkBooleanResult: integerReceiver< integerArgument >>> >>> InterpreterPrimitives>>primitiveLessThan >>> | integerReceiver integerArgument | >>> integerArgument := self popInteger. >>> integerReceiver := self popInteger. >>> self checkBooleanResult: integerReceiver< integerArgument >>> >>> and #popInteger also same (it fails if value on stack are not >>> smallinteger). >>> So, in Squeak VM comparison primitive also fails, >>> which should lead to evaluating failure code. >> Cog has translation methods for those primitives in cogit.c, see >> genSmallIntegerComparison. > > So , i think the problem is, that #genSmallIntegerComparison: (and friends) > generating code for comparing integers only and falls back to normal > send when it fails, > without attempting to use #primitiveFloatLess:thanArg: . genSmallIntegerComparison(sqInt jumpOpcode) { AbstractInstruction *jumpFail; AbstractInstruction *jumpTrue; gMoveRR(Arg0Reg, TempReg); jumpFail = genJumpNotSmallIntegerInScratchReg(TempReg); Assuming genJumpNotSmallIntegerInScratchReg is an accurate name, I'd say yes. :) Cheers, Henry |
Btw, i don't like this code: self assertClassOf: floatOrInt is: (objectMemory splObj: ClassFloat) compactClassIndex: ClassFloatCompactIndex. the purpose of it is to check if given object is an instance of compact class, and if it is ,then you don't have to fetch class (because you only need to check that compact index is same as compact index for class you are checking for). So, it says that (objectMemory splObj: ClassFloat) will be optimized away if comparison successfull.. but i think it would be better to use different assertion to be not dependent from compiler optimizations: is: oop instanceOfClass: classObjectIndex compactClassIndex: compactClassIndex "Answer if oop is an instance of the given class. If the class has a (non-zero) compactClassIndex use that to speed up the check. N.B. Inlining should result in classOop not being accessed if compactClassIndex is non-zero." | ccIndex | <inline: true> (self isIntegerObject: oop) ifTrue: [^false]. ccIndex := self compactClassIndexOf: oop. compactClassIndex ~= 0 ifTrue: [^compactClassIndex == ccIndex]. ^ccIndex = 0 and: [((self classHeader: oop) bitAnd: AllButTypeMask) = (self splObj: classObjectIndex)] so the difference that you passing a class index as argument, but not class itself. So even if compiler will fail to optimize it, it won't cost you extra load from special objects array. So instead of writing: self assertClassOf: floatOrInt is: (objectMemory splObj: ClassFloat) compactClassIndex: ClassFloatCompactIndex. the code can be refactored to use: self assertClassOf: floatOrInt isSplObj: ClassFloat compactClassIndex: ClassFloatCompactIndex. (which calls #is:instanceOfClass:compactClassIndex: above) -- Best regards, Igor Stasenko AKA sig. |
On 2 May 2011 15:46, Igor Stasenko <[hidden email]> wrote: > Btw, > > i don't like this code: > > self assertClassOf: floatOrInt > is: (objectMemory splObj: ClassFloat) > compactClassIndex: ClassFloatCompactIndex. > btw, Cog is suspectible to have bugs if during run time you will change a class to be no longer compact or (and then installing a different class to be compact on same compact classes array index as before). To avoid that, there should be a primitive which should refresh compact indices for most used classes, to avoid bugs. (The StackInterpreter>>checkAssumedCompactClasses should be run each time when some class become (un)compact). -- Best regards, Igor Stasenko AKA sig. |
No. Instead certain compact incomes should be mandated. It is absurd to throw away performance and expend effort supporting complexity for flexibility that is essentially never used and in maintaining a scheme that is only partially effective. Eliot (phone) On May 2, 2011, at 7:20 AM, Igor Stasenko <[hidden email]> wrote: > > On 2 May 2011 15:46, Igor Stasenko <[hidden email]> wrote: >> Btw, >> >> i don't like this code: >> >> self assertClassOf: floatOrInt >> is: (objectMemory splObj: ClassFloat) >> compactClassIndex: ClassFloatCompactIndex. >> > > btw, Cog is suspectible to have bugs if during run time you will > change a class to be no longer compact or > (and then installing a different class to be compact on same compact > classes array index as before). > > To avoid that, there should be a primitive which should refresh > compact indices for most used classes, > to avoid bugs. > > (The StackInterpreter>>checkAssumedCompactClasses should be run each > time when some class become (un)compact). > > -- > Best regards, > Igor Stasenko AKA sig. |
In reply to this post by Henrik Sperre Johansen
Hi Henrik, Eliot (phone) On May 2, 2011, at 3:12 AM, Henrik Sperre Johansen <[hidden email]> wrote: > As per my comment on the recent Morphic performance graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59) on a Cog VM these primitives fail with a Float parameter, which leads to a huge performance hit when comparing Ints to Floats by doing silly things in the fallback code. > > Cog: > [1 to: 2000000 do: [:i | > i < 2354.234. > i <= 2354.234. > i >= 2354.234. > i > 2354.234.]] timeToRun 26594 > > Trunk: > [1 to: 2000000 do: [:i | > i < 2354.234. > i <= 2354.234. > i >= 2354.234. > i > 2354.234.]] timeToRun 229 > > Should this be changed in the VM, I think so. When I first wrote the SmallInteger translated prims I hadn't yet written the JIT support for floats and so couldn't write int/float comparison. Now all the support is there and it should be straight-forward. Do you fancy trying to write this yourself? Would be a fun exercise. Let me know and I can hand-hold with using the simulator. Best Eliot (phone) > or is the difference for pure int/int comparition large enough that we should instead change > Float>>adaptToInteger: andCompare: > to use the corresponding comparitions with Float as receiver, which does work? > That's still slower than trunk in my image, but quite a bit better, above test takes about 1s. > > Cheers, > Henry |
In reply to this post by Eliot Miranda-2
On Mon, May 2, 2011 at 6:11 PM, Eliot Miranda <[hidden email]> wrote:
+9999 Compact classes didn't change in the last....how many years? In fact, (and I have already sent an email with this) there are only 15 compact classes. This mean that we can even be using 4 bits instead of 5.
-- Mariano http://marianopeck.wordpress.com |
In reply to this post by Igor Stasenko
igor can you add bug entry to cog? Stef On May 2, 2011, at 4:20 PM, Igor Stasenko wrote: > > On 2 May 2011 15:46, Igor Stasenko <[hidden email]> wrote: >> Btw, >> >> i don't like this code: >> >> self assertClassOf: floatOrInt >> is: (objectMemory splObj: ClassFloat) >> compactClassIndex: ClassFloatCompactIndex. >> > > btw, Cog is suspectible to have bugs if during run time you will > change a class to be no longer compact or > (and then installing a different class to be compact on same compact > classes array index as before). > > To avoid that, there should be a primitive which should refresh > compact indices for most used classes, > to avoid bugs. > > (The StackInterpreter>>checkAssumedCompactClasses should be run each > time when some class become (un)compact). > > -- > Best regards, > Igor Stasenko AKA sig. |
In reply to this post by Eliot Miranda-2
On 2 May 2011 18:11, Eliot Miranda <[hidden email]> wrote: > > No. Instead certain compact incomes should be mandated. It is absurd to throw away performance and expend effort supporting complexity for flexibility that is essentially never used and in maintaining a scheme that is only partially effective. > compact classes are pain in the ... so i would not cry if we get rid of them. but right now i see that potentially i could break things if i start replacing one compact class with another. > Eliot (phone) > > On May 2, 2011, at 7:20 AM, Igor Stasenko <[hidden email]> wrote: > >> >> On 2 May 2011 15:46, Igor Stasenko <[hidden email]> wrote: >>> Btw, >>> >>> i don't like this code: >>> >>> self assertClassOf: floatOrInt >>> is: (objectMemory splObj: ClassFloat) >>> compactClassIndex: ClassFloatCompactIndex. >>> >> >> btw, Cog is suspectible to have bugs if during run time you will >> change a class to be no longer compact or >> (and then installing a different class to be compact on same compact >> classes array index as before). >> >> To avoid that, there should be a primitive which should refresh >> compact indices for most used classes, >> to avoid bugs. >> >> (The StackInterpreter>>checkAssumedCompactClasses should be run each >> time when some class become (un)compact). >> >> -- >> Best regards, >> Igor Stasenko AKA sig. > -- Best regards, Igor Stasenko AKA sig. |
On Mon, May 2, 2011 at 12:39 PM, Igor Stasenko <[hidden email]> wrote:
Doctor, doctor, it hurts when I... Doctor: don't do that.
|
In reply to this post by stephane ducasse-2
On 2 May 2011 18:19, stephane ducasse <[hidden email]> wrote: > > igor can you add bug entry to cog? sure http://code.google.com/p/cog/issues/detail?id=40 maybe someday someone could find a time and address it. > > Stef > -- Best regards, Igor Stasenko AKA sig. |
In reply to this post by Eliot Miranda-2
I always refused to learn x86 assembler, but by code imitation I can give my own try in attachment. Note that I did not use the trick to invert FP comparison operands since this does not seem necessary. Nicolas 2011/5/2 Eliot Miranda <[hidden email]>: > > Hi Henrik, > > Eliot (phone) > > On May 2, 2011, at 3:12 AM, Henrik Sperre Johansen <[hidden email]> wrote: > >> As per my comment on the recent Morphic performance graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59) on a Cog VM these primitives fail with a Float parameter, which leads to a huge performance hit when comparing Ints to Floats by doing silly things in the fallback code. >> >> Cog: >> [1 to: 2000000 do: [:i | >> i < 2354.234. >> i <= 2354.234. >> i >= 2354.234. >> i > 2354.234.]] timeToRun 26594 >> >> Trunk: >> [1 to: 2000000 do: [:i | >> i < 2354.234. >> i <= 2354.234. >> i >= 2354.234. >> i > 2354.234.]] timeToRun 229 >> >> Should this be changed in the VM, > > I think so. When I first wrote the SmallInteger translated prims I hadn't yet written the JIT support for floats and so couldn't write int/float comparison. Now all the support is there and it should be straight-forward. Do you fancy trying to write this yourself? Would be a fun exercise. Let me know and I can hand-hold with using the simulator. > > > Best > Eliot (phone) > > >> or is the difference for pure int/int comparition large enough that we should instead change >> Float>>adaptToInteger: andCompare: >> to use the corresponding comparitions with Float as receiver, which does work? >> That's still slower than trunk in my image, but quite a bit better, above test takes about 1s. >> >> Cheers, >> Henry > SimpleStackBasedCogit-genSmallIntegerComparisonorDoubleComparison.st (3K) Download Attachment |
And if genSmallIntegerComparison:orDoubleComparison: is correct, then usage shall be quite straight forward Nicolas 2011/5/3 Nicolas Cellier <[hidden email]>: > I always refused to learn x86 assembler, but by code imitation I can > give my own try in attachment. > Note that I did not use the trick to invert FP comparison operands > since this does not seem necessary. > > Nicolas > > > 2011/5/2 Eliot Miranda <[hidden email]>: >> >> Hi Henrik, >> >> Eliot (phone) >> >> On May 2, 2011, at 3:12 AM, Henrik Sperre Johansen <[hidden email]> wrote: >> >>> As per my comment on the recent Morphic performance graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59) on a Cog VM these primitives fail with a Float parameter, which leads to a huge performance hit when comparing Ints to Floats by doing silly things in the fallback code. >>> >>> Cog: >>> [1 to: 2000000 do: [:i | >>> i < 2354.234. >>> i <= 2354.234. >>> i >= 2354.234. >>> i > 2354.234.]] timeToRun 26594 >>> >>> Trunk: >>> [1 to: 2000000 do: [:i | >>> i < 2354.234. >>> i <= 2354.234. >>> i >= 2354.234. >>> i > 2354.234.]] timeToRun 229 >>> >>> Should this be changed in the VM, >> >> I think so. When I first wrote the SmallInteger translated prims I hadn't yet written the JIT support for floats and so couldn't write int/float comparison. Now all the support is there and it should be straight-forward. Do you fancy trying to write this yourself? Would be a fun exercise. Let me know and I can hand-hold with using the simulator. >> >> >> Best >> Eliot (phone) >> >> >>> or is the difference for pure int/int comparition large enough that we should instead change >>> Float>>adaptToInteger: andCompare: >>> to use the corresponding comparitions with Float as receiver, which does work? >>> That's still slower than trunk in my image, but quite a bit better, above test takes about 1s. >>> >>> Cheers, >>> Henry >> > cogitCompareSmallIntegerAndFloat.st (4K) Download Attachment |
Hem, some declaration were missing... and the argument for FP comparison is tricky indeed... Sorry for the noise, but this is a direct live Nicolas 2011/5/3 Nicolas Cellier <[hidden email]>: > And if genSmallIntegerComparison:orDoubleComparison: is correct, then > usage shall be quite straight forward > > Nicolas > > 2011/5/3 Nicolas Cellier <[hidden email]>: >> I always refused to learn x86 assembler, but by code imitation I can >> give my own try in attachment. >> Note that I did not use the trick to invert FP comparison operands >> since this does not seem necessary. >> >> Nicolas >> >> >> 2011/5/2 Eliot Miranda <[hidden email]>: >>> >>> Hi Henrik, >>> >>> Eliot (phone) >>> >>> On May 2, 2011, at 3:12 AM, Henrik Sperre Johansen <[hidden email]> wrote: >>> >>>> As per my comment on the recent Morphic performance graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59) on a Cog VM these primitives fail with a Float parameter, which leads to a huge performance hit when comparing Ints to Floats by doing silly things in the fallback code. >>>> >>>> Cog: >>>> [1 to: 2000000 do: [:i | >>>> i < 2354.234. >>>> i <= 2354.234. >>>> i >= 2354.234. >>>> i > 2354.234.]] timeToRun 26594 >>>> >>>> Trunk: >>>> [1 to: 2000000 do: [:i | >>>> i < 2354.234. >>>> i <= 2354.234. >>>> i >= 2354.234. >>>> i > 2354.234.]] timeToRun 229 >>>> >>>> Should this be changed in the VM, >>> >>> I think so. When I first wrote the SmallInteger translated prims I hadn't yet written the JIT support for floats and so couldn't write int/float comparison. Now all the support is there and it should be straight-forward. Do you fancy trying to write this yourself? Would be a fun exercise. Let me know and I can hand-hold with using the simulator. >>> >>> >>> Best >>> Eliot (phone) >>> >>> >>>> or is the difference for pure int/int comparition large enough that we should instead change >>>> Float>>adaptToInteger: andCompare: >>>> to use the corresponding comparitions with Float as receiver, which does work? >>>> That's still slower than trunk in my image, but quite a bit better, above test takes about 1s. >>>> >>>> Cheers, >>>> Henry >>> >> > cogitCompareSmallIntegerAndFloat.st (6K) Download Attachment |
Apart another declaration bug (FP missing in function name...) there is a killer : StackToRegisterMappingCogit inherits silently from SimpleStackBasedCogit>>#genSmallIntegerComparison:orDoubleComparison: though it does not share the stack structure. This is fatal... So an override StackToRegisterMappingCogit>>#genSmallIntegerComparison:orDoubleComparison: is mandatory Bad, bad inheritance... Now compiling the VM again... Nicolas 2011/5/3 Nicolas Cellier <[hidden email]>: > Hem, some declaration were missing... and the argument for FP > comparison is tricky indeed... > Sorry for the noise, but this is a direct live > > Nicolas > > 2011/5/3 Nicolas Cellier <[hidden email]>: >> And if genSmallIntegerComparison:orDoubleComparison: is correct, then >> usage shall be quite straight forward >> >> Nicolas >> >> 2011/5/3 Nicolas Cellier <[hidden email]>: >>> I always refused to learn x86 assembler, but by code imitation I can >>> give my own try in attachment. >>> Note that I did not use the trick to invert FP comparison operands >>> since this does not seem necessary. >>> >>> Nicolas >>> >>> >>> 2011/5/2 Eliot Miranda <[hidden email]>: >>>> >>>> Hi Henrik, >>>> >>>> Eliot (phone) >>>> >>>> On May 2, 2011, at 3:12 AM, Henrik Sperre Johansen <[hidden email]> wrote: >>>> >>>>> As per my comment on the recent Morphic performance graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59) on a Cog VM these primitives fail with a Float parameter, which leads to a huge performance hit when comparing Ints to Floats by doing silly things in the fallback code. >>>>> >>>>> Cog: >>>>> [1 to: 2000000 do: [:i | >>>>> i < 2354.234. >>>>> i <= 2354.234. >>>>> i >= 2354.234. >>>>> i > 2354.234.]] timeToRun 26594 >>>>> >>>>> Trunk: >>>>> [1 to: 2000000 do: [:i | >>>>> i < 2354.234. >>>>> i <= 2354.234. >>>>> i >= 2354.234. >>>>> i > 2354.234.]] timeToRun 229 >>>>> >>>>> Should this be changed in the VM, >>>> >>>> I think so. When I first wrote the SmallInteger translated prims I hadn't yet written the JIT support for floats and so couldn't write int/float comparison. Now all the support is there and it should be straight-forward. Do you fancy trying to write this yourself? Would be a fun exercise. Let me know and I can hand-hold with using the simulator. >>>> >>>> >>>> Best >>>> Eliot (phone) >>>> >>>> >>>>> or is the difference for pure int/int comparition large enough that we should instead change >>>>> Float>>adaptToInteger: andCompare: >>>>> to use the corresponding comparitions with Float as receiver, which does work? >>>>> That's still slower than trunk in my image, but quite a bit better, above test takes about 1s. >>>>> >>>>> Cheers, >>>>> Henry >>>> >>> >> > StackToRegisterMappingCogit-genSmallIntegerComparisonorDoubleComparison.st (2K) Download Attachment |
OK, with SimpleCogit: [1 to: 2000000 do: [:i | i < 2354.234. i <= 2354.234. i >= 2354.234. i > 2354.234.]] timeToRun 69 vs 4.2.5 VM: [1 to: 2000000 do: [:i | i < 2354.234. i <= 2354.234. i >= 2354.234. i > 2354.234.]] timeToRun 299 StackToRegisterMappingCogit: crash... I don't get the x86 certification yet :( Nicolas 2011/5/3 Nicolas Cellier <[hidden email]>: > Apart another declaration bug (FP missing in function name...) there > is a killer : > > StackToRegisterMappingCogit inherits silently from > SimpleStackBasedCogit>>#genSmallIntegerComparison:orDoubleComparison: > though it does not share the stack structure. This is fatal... > > So an override StackToRegisterMappingCogit>>#genSmallIntegerComparison:orDoubleComparison: > is mandatory > > Bad, bad inheritance... > > Now compiling the VM again... > > Nicolas > > > 2011/5/3 Nicolas Cellier <[hidden email]>: >> Hem, some declaration were missing... and the argument for FP >> comparison is tricky indeed... >> Sorry for the noise, but this is a direct live >> >> Nicolas >> >> 2011/5/3 Nicolas Cellier <[hidden email]>: >>> And if genSmallIntegerComparison:orDoubleComparison: is correct, then >>> usage shall be quite straight forward >>> >>> Nicolas >>> >>> 2011/5/3 Nicolas Cellier <[hidden email]>: >>>> I always refused to learn x86 assembler, but by code imitation I can >>>> give my own try in attachment. >>>> Note that I did not use the trick to invert FP comparison operands >>>> since this does not seem necessary. >>>> >>>> Nicolas >>>> >>>> >>>> 2011/5/2 Eliot Miranda <[hidden email]>: >>>>> >>>>> Hi Henrik, >>>>> >>>>> Eliot (phone) >>>>> >>>>> On May 2, 2011, at 3:12 AM, Henrik Sperre Johansen <[hidden email]> wrote: >>>>> >>>>>> As per my comment on the recent Morphic performance graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59) on a Cog VM these primitives fail with a Float parameter, which leads to a huge performance hit when comparing Ints to Floats by doing silly things in the fallback code. >>>>>> >>>>>> Cog: >>>>>> [1 to: 2000000 do: [:i | >>>>>> i < 2354.234. >>>>>> i <= 2354.234. >>>>>> i >= 2354.234. >>>>>> i > 2354.234.]] timeToRun 26594 >>>>>> >>>>>> Trunk: >>>>>> [1 to: 2000000 do: [:i | >>>>>> i < 2354.234. >>>>>> i <= 2354.234. >>>>>> i >= 2354.234. >>>>>> i > 2354.234.]] timeToRun 229 >>>>>> >>>>>> Should this be changed in the VM, >>>>> >>>>> I think so. When I first wrote the SmallInteger translated prims I hadn't yet written the JIT support for floats and so couldn't write int/float comparison. Now all the support is there and it should be straight-forward. Do you fancy trying to write this yourself? Would be a fun exercise. Let me know and I can hand-hold with using the simulator. >>>>> >>>>> >>>>> Best >>>>> Eliot (phone) >>>>> >>>>> >>>>>> or is the difference for pure int/int comparition large enough that we should instead change >>>>>> Float>>adaptToInteger: andCompare: >>>>>> to use the corresponding comparitions with Float as receiver, which does work? >>>>>> That's still slower than trunk in my image, but quite a bit better, above test takes about 1s. >>>>>> >>>>>> Cheers, >>>>>> Henry >>>>> >>>> >>> >> > |
OK, easy, I had a reference to ClassReg instead of Arg0Reg (copy/paste error from super). My feeling is that it is very uncomfortable to program this part... Since we mapped our local variables and arguments to an equivalent of global variables (registers Arg0Reg etc), then no compiler will tell us that this register is used before assigned or never used or what... Far, far away from Smalltalk safe lands... Here is a new try attached: [1 to: 2000000 do: [:i | i < 2354.234. i <= 2354.234. i >= 2354.234. i > 2354.234.]] timeToRun 71 A bit slower than SimpleCogit ? Nicolas 2011/5/3 Nicolas Cellier <[hidden email]>: > OK, with SimpleCogit: > [1 to: 2000000 do: [:i | > i < 2354.234. > i <= 2354.234. > i >= 2354.234. > i > 2354.234.]] timeToRun 69 > > vs 4.2.5 VM: > [1 to: 2000000 do: [:i | > i < 2354.234. > i <= 2354.234. > i >= 2354.234. > i > 2354.234.]] timeToRun 299 > > StackToRegisterMappingCogit: > crash... > > I don't get the x86 certification yet :( > > Nicolas > > > 2011/5/3 Nicolas Cellier <[hidden email]>: >> Apart another declaration bug (FP missing in function name...) there >> is a killer : >> >> StackToRegisterMappingCogit inherits silently from >> SimpleStackBasedCogit>>#genSmallIntegerComparison:orDoubleComparison: >> though it does not share the stack structure. This is fatal... >> >> So an override StackToRegisterMappingCogit>>#genSmallIntegerComparison:orDoubleComparison: >> is mandatory >> >> Bad, bad inheritance... >> >> Now compiling the VM again... >> >> Nicolas >> >> >> 2011/5/3 Nicolas Cellier <[hidden email]>: >>> Hem, some declaration were missing... and the argument for FP >>> comparison is tricky indeed... >>> Sorry for the noise, but this is a direct live >>> >>> Nicolas >>> >>> 2011/5/3 Nicolas Cellier <[hidden email]>: >>>> And if genSmallIntegerComparison:orDoubleComparison: is correct, then >>>> usage shall be quite straight forward >>>> >>>> Nicolas >>>> >>>> 2011/5/3 Nicolas Cellier <[hidden email]>: >>>>> I always refused to learn x86 assembler, but by code imitation I can >>>>> give my own try in attachment. >>>>> Note that I did not use the trick to invert FP comparison operands >>>>> since this does not seem necessary. >>>>> >>>>> Nicolas >>>>> >>>>> >>>>> 2011/5/2 Eliot Miranda <[hidden email]>: >>>>>> >>>>>> Hi Henrik, >>>>>> >>>>>> Eliot (phone) >>>>>> >>>>>> On May 2, 2011, at 3:12 AM, Henrik Sperre Johansen <[hidden email]> wrote: >>>>>> >>>>>>> As per my comment on the recent Morphic performance graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59) on a Cog VM these primitives fail with a Float parameter, which leads to a huge performance hit when comparing Ints to Floats by doing silly things in the fallback code. >>>>>>> >>>>>>> Cog: >>>>>>> [1 to: 2000000 do: [:i | >>>>>>> i < 2354.234. >>>>>>> i <= 2354.234. >>>>>>> i >= 2354.234. >>>>>>> i > 2354.234.]] timeToRun 26594 >>>>>>> >>>>>>> Trunk: >>>>>>> [1 to: 2000000 do: [:i | >>>>>>> i < 2354.234. >>>>>>> i <= 2354.234. >>>>>>> i >= 2354.234. >>>>>>> i > 2354.234.]] timeToRun 229 >>>>>>> >>>>>>> Should this be changed in the VM, >>>>>> >>>>>> I think so. When I first wrote the SmallInteger translated prims I hadn't yet written the JIT support for floats and so couldn't write int/float comparison. Now all the support is there and it should be straight-forward. Do you fancy trying to write this yourself? Would be a fun exercise. Let me know and I can hand-hold with using the simulator. >>>>>> >>>>>> >>>>>> Best >>>>>> Eliot (phone) >>>>>> >>>>>> >>>>>>> or is the difference for pure int/int comparition large enough that we should instead change >>>>>>> Float>>adaptToInteger: andCompare: >>>>>>> to use the corresponding comparitions with Float as receiver, which does work? >>>>>>> That's still slower than trunk in my image, but quite a bit better, above test takes about 1s. >>>>>>> >>>>>>> Cheers, >>>>>>> Henry >>>>>> >>>>> >>>> >>> >> > StackToRegisterMappingCogit-genSmallIntegerComparisonorDoubleComparison.st (2K) Download Attachment |
Free forum by Nabble | Edit this page |