Marcel Taeumel uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-mt.1550.mcz
==================== Summary ====================
Name: Kernel-mt.1550 Author: mt Time: 10 January 2024, 10:09:15.266957 am UUID: 8f04eaa3-9dff-3d40-83f5-5783afc41380 Ancestors: Kernel-ct.1549, Kernel-mt.1545
Merge Kernel-mt.1545: - Propose different fallback for mixed int-float arithmetics to use VM-backed mixed float-int arithmetics for + - * / . Speed-up is about 7x on my machine.
No measurable slowdown for non-float fallback paths.
=============== Diff against Kernel-ct.1549 ===============
Item was changed: ----- Method: SmallInteger>>* (in category 'arithmetic') ----- * aNumber "Primitive. Multiply the receiver by the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 9> + ^ aNumber isFloat + ifTrue: [aNumber * self "exploit mixed arithmetic in float primitives"] + ifFalse: [super * aNumber]! - ^ super * aNumber!
Item was changed: ----- Method: SmallInteger>>+ (in category 'arithmetic') ----- + aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1> + ^ aNumber isFloat + ifTrue: [aNumber + self "exploit mixed arithmetic in float primitives"] + ifFalse: [super + aNumber]! - ^ super + aNumber!
Item was changed: ----- Method: SmallInteger>>- (in category 'arithmetic') ----- - aNumber "Primitive. Subtract the argument from the receiver and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 2> + ^ aNumber isFloat + ifTrue: [aNumber negated + self "exploit mixed arithmetic in float primitives"] + ifFalse: [super - aNumber]! - ^super - aNumber!
Item was changed: ----- Method: SmallInteger>>/ (in category 'arithmetic') ----- / aNumber "Primitive. This primitive (for /) divides the receiver by the argument and returns the result if the division is exact. Fail if the result is not a whole integer. Fail if the argument is 0 or is not a SmallInteger. Optional. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 10> + ^ aNumber isFloat + ifTrue: [(1.0 / aNumber) * self "exploit mixed arithmetic in float primitives"] + ifFalse: [super / aNumber]! - ^super / aNumber!
Hi Marcel, sorry to come late on this, but I think that the acceleration is not correct for division:
Performing a single division implies a single rounding operation and is thus guaranteed to answer the nearest Float to the theoretical result. Taking reciprocal, then multiplying implies 2 rounding operations and thus has no such guarantee.
Example : {3.0/5.0. 3.0*5.0 reciprocal. } #(0.6 0.6000000000000001)
Thus 3/5.0 which did answer the former result will now answer the later which is questionable. For the other operations, I think that the accelerated fallback is correct.
Best wishes for 2024 and happy squeaking!
Le mer. 10 janv. 2024 à 10:09, commits@source.squeak.org a écrit :
Marcel Taeumel uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-mt.1550.mcz
==================== Summary ====================
Name: Kernel-mt.1550 Author: mt Time: 10 January 2024, 10:09:15.266957 am UUID: 8f04eaa3-9dff-3d40-83f5-5783afc41380 Ancestors: Kernel-ct.1549, Kernel-mt.1545
Merge Kernel-mt.1545:
- Propose different fallback for mixed int-float arithmetics to use VM-backed mixed float-int arithmetics for + - * / . Speed-up is about 7x on my machine.
No measurable slowdown for non-float fallback paths.
=============== Diff against Kernel-ct.1549 ===============
Item was changed: ----- Method: SmallInteger>>* (in category 'arithmetic') -----
aNumber "Primitive. Multiply the receiver by the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 9>
^ aNumber isFloat
ifTrue: [aNumber * self "exploit mixed arithmetic in float primitives"]
ifFalse: [super * aNumber]!
^ super * aNumber!
Item was changed: ----- Method: SmallInteger>>+ (in category 'arithmetic') -----
aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1>
^ aNumber isFloat
ifTrue: [aNumber + self "exploit mixed arithmetic in float primitives"]
ifFalse: [super + aNumber]!
^ super + aNumber!
Item was changed: ----- Method: SmallInteger>>- (in category 'arithmetic') -----
aNumber "Primitive. Subtract the argument from the receiver and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 2>
^ aNumber isFloat
ifTrue: [aNumber negated + self "exploit mixed arithmetic in float primitives"]
ifFalse: [super - aNumber]!
^super - aNumber!
Item was changed: ----- Method: SmallInteger>>/ (in category 'arithmetic') ----- / aNumber "Primitive. This primitive (for /) divides the receiver by the argument and returns the result if the division is exact. Fail if the result is not a whole integer. Fail if the argument is 0 or is not a SmallInteger. Optional. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 10>
^ aNumber isFloat
ifTrue: [(1.0 / aNumber) * self "exploit mixed arithmetic in float primitives"]
ifFalse: [super / aNumber]!
^super / aNumber!
Hi Nicolas --
Thanks for taking a look. I reverted the one for #/ and added a commentary. See Kernel-mt.1551
Best, Marcel ________________________________ Von: Nicolas Cellier nicolas.cellier.aka.nice@gmail.com Gesendet: Mittwoch, 10. Januar 2024 17:44 An: squeak-dev@lists.squeakfoundation.org squeak-dev@lists.squeakfoundation.org Betreff: [squeak-dev] Re: The Trunk: Kernel-mt.1550.mcz
Hi Marcel, sorry to come late on this, but I think that the acceleration is not correct for division:
Performing a single division implies a single rounding operation and is thus guaranteed to answer the nearest Float to the theoretical result. Taking reciprocal, then multiplying implies 2 rounding operations and thus has no such guarantee.
Example : {3.0/5.0. 3.0*5.0 reciprocal. } #(0.6 0.6000000000000001)
Thus 3/5.0 which did answer the former result will now answer the later which is questionable. For the other operations, I think that the accelerated fallback is correct.
Best wishes for 2024 and happy squeaking!
Le mer. 10 janv. 2024 à 10:09, commits@source.squeak.org a écrit :
Marcel Taeumel uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-mt.1550.mcz
==================== Summary ====================
Name: Kernel-mt.1550 Author: mt Time: 10 January 2024, 10:09:15.266957 am UUID: 8f04eaa3-9dff-3d40-83f5-5783afc41380 Ancestors: Kernel-ct.1549, Kernel-mt.1545
Merge Kernel-mt.1545:
- Propose different fallback for mixed int-float arithmetics to use VM-backed mixed float-int arithmetics for + - * / . Speed-up is about 7x on my machine.
No measurable slowdown for non-float fallback paths.
=============== Diff against Kernel-ct.1549 ===============
Item was changed: ----- Method: SmallInteger>>* (in category 'arithmetic') -----
aNumber "Primitive. Multiply the receiver by the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 9>
^ aNumber isFloat
ifTrue: [aNumber * self "exploit mixed arithmetic in float primitives"]
ifFalse: [super * aNumber]!
^ super * aNumber!
Item was changed: ----- Method: SmallInteger>>+ (in category 'arithmetic') -----
aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1>
^ aNumber isFloat
ifTrue: [aNumber + self "exploit mixed arithmetic in float primitives"]
ifFalse: [super + aNumber]!
^ super + aNumber!
Item was changed: ----- Method: SmallInteger>>- (in category 'arithmetic') -----
aNumber "Primitive. Subtract the argument from the receiver and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger. Essential. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 2>
^ aNumber isFloat
ifTrue: [aNumber negated + self "exploit mixed arithmetic in float primitives"]
ifFalse: [super - aNumber]!
^super - aNumber!
Item was changed: ----- Method: SmallInteger>>/ (in category 'arithmetic') ----- / aNumber "Primitive. This primitive (for /) divides the receiver by the argument and returns the result if the division is exact. Fail if the result is not a whole integer. Fail if the argument is 0 or is not a SmallInteger. Optional. No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 10>
^ aNumber isFloat
ifTrue: [(1.0 / aNumber) * self "exploit mixed arithmetic in float primitives"]
ifFalse: [super / aNumber]!
^super / aNumber!
squeak-dev@lists.squeakfoundation.org